と
両端キュー名は意味:両端キュー内の削除された要素を挿入することができます。
制限が削除操作を挿入されている場合は両端キューの両端部には、それはあなたがダブルエンドキュー、キューを習得し、より簡単に自然にスタックそうならば、キューまたはスタックに退化します。
以下は、この両端キューである抽象データ型:英語の説明
、A「両端キューは、」アイテムのAリストからなるAデータ構造体であるに対して次の操作が可能な:
プッシュ(X-、D) :項目の挿入X-ONザ・フロントエンドD.の両端キュー
ポップ(D):両端キューからフロント取り除きアイテムDとITを返します。ジェクト(X-、D) :両端キューD.のREARが挿入終了項目X-ON
イジェクト(D)両端キューからREAR取り除きアイテムD:リターンと。
PUSHおよびPOPは、両端キューヘッドインサートと削除操作で
注入し、取り出しが両端キュー後方の挿入および削除操作です。
まず、両端キュー定義する物理的な構造を
#define ElementType int
typedef struct Node *PtrToNode;
struct Node {
ElementType Element;
PtrToNode Next, Last;
};
typedef struct DequeRecord *Deque;
struct DequeRecord {
PtrToNode Front, Rear;
};
図形
ここで小さなパートナーが、私はデータ構造を学ぶとき、前にこのような状況に遭遇したとき、間違った、塗装パットを理解するのは簡単ですよ、ダブルエンドキューが差し込まれようとしていると述べ、グラフィカルな形式がある
が、時間の始まりは、実際に保存され、それは前から始まる、それは配列やリストであるかどうか、だけなのでなっ繰り返し挿入、削除後に透明である、そうではないとリア最初の画像のように、いくつかの小さなパートナーは、間違った場所に行くされている、フロントのインサート前部要素法による端が左へのポインタを追加する最初のプラグは、実際には、前部の先頭の位置が動いていない、好ましくはより良好な書込みヘッドを挿入されています。
まず、リンクリストとして両端キューを作成します
Deque CreateDeque()
{
Deque p;
p = (Deque)malloc(sizeof(struct DequeRecord));
//队列开空间
p->Front = (PtrToNode)malloc(sizeof(struct Node));
//队列头部指向一个新地址
p->Rear = (PtrToNode)malloc(sizeof(struct Node));
//队列尾部也指向一个新地址
p->Rear->Last = p->Front;//头尾相等
p->Front->Next = p->Rear;
p->Front->Last = NULL;
p->Rear->Next = NULL;
return p;
}
プッシュで簡単な十分な結果として、インターネットの形でのみシングルヘッドポインタ、そのため、ポップ、注入、コードの動作を取り出し、それを理解することは困難になります、私の最新の書き込みヒット双頭ノードの一種で、パットの交流もあります実現可能な、多目的スペースの一部が、ほとんど効果ものの。このため4つの統一された操作を、コードも読み良く見えます。
第二段階は、我々は4つの事業の具体的な原則のためのコードを書きます
int Push(ElementType X, Deque D){
struct Node* tmp;
tmp = (struct Node*)malloc(sizeof(struct Node));
//开新的节点
if (!tmp)return 0;
tmp->Element = X;//给新节点赋值
tmp->Last = D->Front;
tmp->Next = D->Front->Next;
D->Front->Next->Last = tmp;
D->Front->Next = tmp;
return 1;//对其进行新节点头插入双链表的写法
}
ElementType Pop(Deque D)
{
//队列为空
if (D->Front->Next == D->Rear)return ERROR;
//删除头部结点的操作
int num = D->Front->Next->Element;
PtrToNode tmp = D->Front->Next;
D->Front->Next = tmp->Next;
tmp->Next->Last = D->Front;
free(tmp);
return num;
}
int Inject(ElementType X, Deque D)
{
struct Node* tmp;
tmp = (struct Node*)malloc(sizeof(struct Node));
//开新的节点
if (!tmp)return 0;
tmp->Element = X;//给新结点赋值
tmp->Next = D->Rear;
tmp->Last = D->Rear->Last;
D->Rear->Last->Next = tmp;
D->Rear->Last = tmp;
return 1;//对其进行新节点头插入双链表的写法
}
ElementType Eject(Deque D)
{
//队列为空
if (D->Front->Next == D->Rear)return ERROR;
//删除尾部的结点
int num = D->Rear->Last->Element;
PtrToNode tmp = D->Rear->Last;
D->Rear->Last = tmp->Last;
tmp->Last->Next = D->Rear;
free(tmp);
return num;
}
4操作は、他のオンライン書き込み、および統一操作、尾と同じ操作の頭よりもはるかに簡単ですが、フロントとリアの最後と次の変更は、最も重要なことは、より良いと比較され、テールのヘッドノード方法をプラグインすることではありません、ノードは挿入し、挿入接合点を決定していません。
最後に、完全なコードを貼り付け、あなたが達成するために自分自身を試すことができます
#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;
};
//主函数入口
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;
}
//push,pop,inject,enject4种操作的具体形式
int Push(ElementType X, Deque D){
struct Node* tmp;
tmp = (struct Node*)malloc(sizeof(struct Node));//开新的节点
if (!tmp)return 0;
tmp->Element = X;//赋值
tmp->Last = D->Front;
tmp->Next = D->Front->Next;
D->Front->Next->Last = tmp;
D->Front->Next = tmp;
return 1;
}
ElementType Pop(Deque D)
{
//队列为空
if (D->Front->Next == D->Rear)return ERROR;
int num = D->Front->Next->Element;
PtrToNode tmp = D->Front->Next;
D->Front->Next = tmp->Next;
tmp->Next->Last = D->Front;
free(tmp);
return num;
}
int Inject(ElementType X, Deque D)
{
struct Node* tmp;
tmp = (struct Node*)malloc(sizeof(struct Node));//开新的节点
if (!tmp)return 0;
tmp->Element = X;//赋值
tmp->Next = D->Rear;
tmp->Last = D->Rear->Last;
D->Rear->Last->Next = tmp;
D->Rear->Last = tmp;
return 1;
}
ElementType Eject(Deque D)
{
if (D->Front->Next == D->Rear)return ERROR;
int num = D->Rear->Last->Element;
PtrToNode tmp = D->Rear->Last;
D->Rear->Last = tmp->Last;
tmp->Last->Next = D->Rear;
free(tmp);
return num;
}
//输入判断入口
Operation GetOp()
{
char a[111];
scanf("%s", a);
//push, pop, inject, eject, end
if (!strcmp("Push", a))
return push;
if (!strcmp("Pop", a))
return pop;
if (!strcmp("Inject", a))
return inject;
if (!strcmp("Eject", a))
return eject;
if (!strcmp("End", a))
return end;
}
//打印函数
void PrintDeque(Deque D)
{
while (D->Front != D->Rear)
{
printf("%d ", Pop(D));
}
puts("");
}
//声明:内部代码有部分使用pat