Deque (双端队列)介绍,附源码

来源:互联网 发布:电脑流量查询软件 编辑:程序博客网 时间:2024/06/18 14:31
Deque,为双端操作队列。约定在队头的进出操作为push和pop, 在队尾进出操作为inject和eject。每个节点存在Data, Next, Last分别指数据, 下一个, 上一个。而对于多个节点组成的队列, 存在Front和Rear分别指队头和队尾。详细定义见源代码。
Push和Pop操作在队头进行, D->Front->Next为第一个数据,Push将新的节点p插入D->Front->Next前, 即三个主要节点顺序为D->Front p D->Front->Next, D->Front 为p的Last, D->Front->Next 为p的Next, D->Front->Next为p。Pop将D->Front->Next弹出, D->Front->Next置为D->Front->Next->Next。

Inject和Eject则在队尾进行, 与D->Front不同的是, 在Inject后, D->Rear将不再是最后一个, 即p->Last = D->Rear。

#include <stdio.h>#include <stdlib.h>#define ElementType int#define ERROR 1e5typedef enum { push, pop, inject, eject, end } Operation;typedef struct Node *PtrToNode;struct Node {ElementType Element;PtrToNode Next, Last;//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;}Deque CreateDeque(){Deque q = (Deque)malloc(sizeof(*(Deque)NULL));q->Front = (PtrToNode)malloc(sizeof(*(PtrToNode)NULL));q->Front->Last = q->Front->Next = NULL;q->Rear = q->Front;return q;}int Push(ElementType X, Deque D){PtrToNode p;p = (PtrToNode)malloc(sizeof(*(PtrToNode)NULL));if (p == NULL) return 0; //Verify p->Element = X;p->Last = D->Front; //结点p的Last 指向D的前端, 将p置于队头p->Next = D->Front->Next;D->Front->Next = p;if (D->Rear == D->Front)D->Rear = p;else p->Next->Last = p;return 1;}ElementType Pop(Deque D){if (D->Front == D->Rear)return ERROR;ElementType e;PtrToNode p = D->Front->Next;e = p->Element;D->Front->Next = p->Next;if (p->Next)D->Front->Next->Last = D->Front;else D->Rear = D->Front;free(p);return e;}int Inject(ElementType X, Deque D){PtrToNode p;p = (PtrToNode)malloc(sizeof(*(PtrToNode)NULL));if (p == NULL) return 0;p->Element = X;p->Last = D->Rear;p->Next = NULL;D->Rear->Next = p;D->Rear = p;return 1;}ElementType Eject(Deque D){if (D->Front == D->Rear)return ERROR;ElementType e;PtrToNode p = D->Rear;e = p->Element;p->Last->Next = NULL;D->Rear = p->Last;free(p);return e;}                   


0 0