C语言链表实现双端队列

6-1 Deque (25 point(s))

A "deque" is a data structure consisting of a list of items, on which the following operations are possible:

  • Push(X,D): Insert item X on the front end of deque D.
  • Pop(D): Remove the front item from deque D and return it.
  • Inject(X,D): Insert item X on the rear end of deque D.
  • Eject(D): Remove the rear item from deque D and return it. Write routines to support the deque that take O(1) time per operation.

Format of functions:

Deque CreateDeque();
int Push( ElementType X, Deque D );
ElementType Pop( Deque D );
int Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

where Deque is defined as the following:

typedef struct Node *PtrToNode;
struct Node {
    ElementType Element;
    PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
    PtrToNode Front, Rear;
};

Here the deque is implemented by a doubly linked list with a header. Front and Rear point to the two ends of the deque respectively. Front always points to the header. The deque is empty when Front and Rear both point to the same dummy header. Note: Push and Inject are supposed to return 1 if the operations can be done successfully, or 0 if fail. If the deque is empty, Pop and Eject must return ERROR which is defined by the judge program.

Sample program of judge:

#include <stdio.h>
#include <stdlib.h>

#define ElementType int
#define ERROR 1e5
typedef enum { push, pop, inject, eject, end } Operation;

typedef struct Node *PtrToNode;
struct Node {
    ElementType Element;
    PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
    PtrToNode Front, Rear;
};
Deque CreateDeque();
int Push( ElementType X, Deque D );
ElementType Pop( Deque D );
int Inject( ElementType X, Deque D );
ElementType Eject( Deque D );

Operation GetOp();          /* details omitted */
void PrintDeque( Deque D ); /* details omitted */

int main()
{
    ElementType X;
    Deque D;
    int done = 0;

    D = CreateDeque();
    while (!done) {
        switch(GetOp()) {
        case push: 
            scanf("%d", &X);
            if (!Push(X, D)) printf("Memory is Full!\n");
            break;
        case pop:
            X = Pop(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            break;
        case inject: 
            scanf("%d", &X);
            if (!Inject(X, D)) printf("Memory is Full!\n");
            break;
        case eject:
            X = Eject(D);
            if ( X==ERROR ) printf("Deque is Empty!\n");
            break;
        case end:
            PrintDeque(D);
            done = 1;
            break;
        }
    }
    return 0;
}

/* Your function will be put here */

Sample Input:

Pop
Inject 1
Pop
Eject
Push 1
Push 2
Eject
Inject 3
End

Sample Output:

Deque is Empty!
Deque is Empty!
Inside Deque: 2 3

 首先是初始化函数,返回一个空双端队列

注意,这个双端队列带有一个头节点

Push操作将数据加入到双端队列头部

Pop操作弹出双端队列头部元素

Inject操作在尾部插入一个元素

Eject操作弹出尾部元素

双向链表操作要仔细细致。

/* Your function will be put here */
Deque CreateDeque()
{
	Deque deque = (Deque)malloc(sizeof(struct DequeRecord));
	PtrToNode temp = (PtrToNode)malloc(sizeof(struct Node));
	temp->Last = NULL;
	temp->Next = NULL;
	deque->Front = temp;
	deque->Rear = temp;
	return deque;

}

int Push(ElementType X, Deque D)
{
	PtrToNode temp;
	temp = (PtrToNode)malloc(sizeof(struct Node));
	if (!temp)
		return 0;
	temp->Element = X;
	// 空队列情况
	if (D->Front == D->Rear)
	{
		D->Front->Next = temp;
		temp->Last = D->Front;
		temp->Next = NULL;
		D->Rear = temp;
		return 1;
	}
	// 一般情况
	temp->Next = D->Front->Next;
	temp->Last = D->Front;
	D->Front->Next->Last = temp;
	D->Front->Next = temp;
	return 1;
	
}

ElementType Pop(Deque D)
{
	
	PtrToNode temp;
	int X;
	// 空队列
	if (D->Front == D->Rear)
		return ERROR;

	temp = D->Front->Next;
	X = temp->Element;
	// 如果只有一个节点的情况
	if (D->Front->Next == D->Rear)
	{
		D->Rear = D->Front;
		D->Rear->Next = NULL;
		free(temp);
		return X;
	}
	// 一般情况
	temp->Next->Last = D->Front;
	D->Front->Next = temp->Next;
	free(temp);
	return X;
}

// 末尾添加一个元素
int Inject(ElementType X, Deque D)
{
	PtrToNode temp;
	temp = (PtrToNode)malloc(sizeof(struct Node));
	if (!temp)
		return 0;
	temp->Element = X;
	// 空队列
	if (D->Front == D->Rear)
	{
		D->Front->Next = temp;
		temp->Last = D->Front;
		D->Rear = temp;
		return 1;
	}
	D->Rear->Next = temp;
	temp->Next = NULL;
	temp->Last = D->Rear;
	D->Rear = temp;
	return 1;
}

// 从末尾移除一个元素
ElementType Eject(Deque D)
{
	PtrToNode temp;
	int X;
	if (D->Front == D->Rear)
		return ERROR;

	temp = D->Rear;
	X = temp->Element;
	D->Rear = temp->Last;
	D->Rear->Next = NULL;
	free(temp);
	return X;
}

猜你喜欢

转载自blog.csdn.net/wwxy1995/article/details/83515053