6-7 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 这个题只要能明白双向队列的功能原理实现就好说了
//模型:front不动,每次插入的时候是在front和它下一个节点之间插入,而rear每次都是移动的,每次都是插到后面,并且rear每次都要 Deque CreateDeque(){//移动指向最后一个上。 Deque p; p = (Deque)malloc(sizeof(struct DequeRecord));//创建头尾指针 p->Front = (PtrToNode)malloc(sizeof(struct Node));//在头上先创建一个虚的节点 p->Front->Last = NULL;//前一个为null说明队列左边没东西 p->Rear = p->Front;//左右相同指向同一个 p->Rear->Next = NULL;//后一个为null说明右边没有东西 return p; } int Push( ElementType X, Deque D ){//每次在front和下一个节点之间插入 struct Node* temp; temp = (struct Node*)malloc(sizeof(struct Node)); if(!temp)return 0;//内存满了,申请失败 temp->Element = X;//赋值 if(D->Front==D->Rear){//如果是个空双端队列 D->Front->Next = temp;//插入第一个点 temp->Last = D->Front;//回指向front D->Rear = temp;//rear指针移动指向第一个新插入的,代表从左边进入的第一个最靠近右边 temp->Next = NULL;//第一次在左边进入的第一个点下一个将不再指向任何东西,因为每次 return 1; //都在前一个插入,第一个点会越来越远 } //一般情况 temp->Next = D->Front->Next;//新节点下一个指向原来front指向的下一个 temp->Last = D->Front;//新节点的前一个指向fronr D->Front->Next->Last = temp;//front原来所值元素的前一个指向新的节点 D->Front->Next = temp;//front的下一个指向新节点 return 1; } ElementType Pop( Deque D ){ if(D->Front==D->Rear) return ERROR;//如果空队列返回错误 int temp = D->Front->Next->Element;//保存pop出的值 struct Node* t = D->Front->Next;//保存它是为了最后把它内存释放掉 if(D->Front->Next==D->Rear){//队列中只有一个元素的时候 D->Rear = D->Front;//删除后rear前移使得rear和front相等 D->Rear->Next = NULL;//虚节点指向空 free(t); return temp; } //一般情况 D->Front->Next->Next->Last = D->Front;//我们要删除front的前一个所以删除之后front前一个的前一个的Last应该指回Front D->Front->Next = D->Front->Next->Next;//同理front下一个应该是原来没删前下一个的下一个 free(t); return temp; } int Inject( ElementType X, Deque D ){//从右边插入就直接插到后面,然后rear后移 struct Node* temp = (struct Node*)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;//和push的一样 } //一般情况 D->Rear->Next = temp;//rear下一个等于新节点 temp->Last = D->Rear;//新节点前一个等于现在rear指的点 temp->Next = NULL;//temp的下一个指向空 D->Rear = temp;//rear右移到当前点 return 1; } ElementType Eject( Deque D ){ if(D->Front==D->Rear){//空队列返回错误 return ERROR; } int temp = D->Rear->Element;//保存值 struct Node* t = D->Rear; D->Rear = D->Rear->Last;//删掉节点rear指回前一个节点 D->Rear->Next = NULL;//现在节点为最后一个,所以指向空 free(t); return temp; }