Deque (雙端佇列)介紹,附原始碼
阿新 • • 發佈:2019-01-28
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 1e5 typedef 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; }