我真的不喜歡寫代碼
隊列的特點
- 先進先出,即只能從隊尾插入元素,從隊頭刪除元素
隊列的鏈式存儲結構
#include<stdio.h>
#include <stdlib.h>
#include<malloc.h>
typedef struct QNode
{
int date;
struct QNode *next;
}QNode ,*QueuePtr;
typedef struct
{
int size; //記錄隊列長度
QueuePtr front; //頭指針
QueuePtr rear; //尾指針
}LinkQueue;
//初始化
void InitQueue(LinkQueue *Q)
{
Q->front=Q->rear=(QNode *)malloc(sizeof(QNode));
if(!Q->front)
exit(0);
Q->rear->next=NULL;
Q->size=0;
}
//在隊尾插入元素
void InsertQueue(LinkQueue *Q,int e)
{
QNode *p;
p=(QueuePtr)malloc(sizeof(QNode));
if(p==NULL)
exit(0);
p->date=e;
Q->rear->next=p;
Q->rear=p;
Q->rear->next=NULL;
Q->size++;
}
//刪除隊頭元素
void Pop_Queue(LinkQueue *Q)
{
Q->front=Q->front->next;
free(Q->front);
Q->size--;
}
//向隊列輸入數據
void Push_Queue(LinkQueue *Q)
{
int e;
QNode *p=NULL;
printf("請輸入數據:\n");
for(int i=0;;i++) //
{
scanf("%d",&e);
if(Q->size==0) //當插入第一個元素時
{
Q->front->date=e;
Q->rear=Q->front; //頭尾指針都指向第一個結點
Q->size++;
}
else
{
p=(QueuePtr)malloc(sizeof(QNode));
if(!p)
exit(0);
p->date=e;
Q->rear->next=p;
Q->rear=p;
Q->rear->next=NULL;
Q->size++;
}
if(getchar()=='\n')
break;
}
}
//打印隊列元素
void ShowQueue(LinkQueue *Q)
{
printf("隊列內的元素為:\n");
int e;
QNode *p;
p=Q->front;
for(int i=0;i<Q->size;i++)
{
e=p->date;
printf("%d ",e);
p=p->next;
}
printf("\n");
}
int main()
{
LinkQueue Q,*p;
p=&Q;
Push_Queue(p);
ShowQueue(p);
InsertQueue(p, 7);
ShowQueue(p);
Pop_Queue(p);
ShowQueue(p);
}
/* 運行結果
請輸入數據:
1 2 3 4 5 6
隊列內的元素為:
1 2 3 4 5 6
隊列內的元素為:
1 2 3 4 5 6 7
隊列內的元素為:
2 3 4 5 6 7
Program ended with exit code: 0
*/
隊列的順序存儲結構---循環隊列
為什么要實現循環隊列(圖片來自嚴蔚敏的數據結構):
上圖是隊列的普通順序存儲,隊列存入數據后,每刪除一個元素,front指針都會上移,則front上一個指向的空間就會被浪費,由此引入循環隊列;
循環隊列的實現原理:
上圖即為循環隊列的示意圖;由圖片可知,當front等於rear時,隊列可能為空,也可能滿,解決辦法有兩種辦法,一是定義一個整型數據記錄元素個數;另一種辦法是犧牲一個存儲空間,當(rear+1)%MIXSIEZ==front時為滿;下面討論第二種方法;
實現過程:
- 插入與刪除時,指針均是在循環鏈表中順時針移動;
- 插入一個元素時,rear=(rear+1)%MIXSIZE,即向后移動一位;
- 刪除一個元素時,front=(front+1)%MIXSIZE,即向后移動一位;
- 判斷隊列為滿:(rear+1)%MIXSIEZ==front
解釋:之所以用(rear+1)%MIXSIEZfront而不用(rear+1)front來判斷隊列是否為滿,是因為,隊列在進行一系列插入與刪除操作后rear可能會小於front,如上圖,5過了之后又回到0,用取模的方法可以解決這個問題,front=(front+1)%MIXSIZE與rear=(rear+1)%MIXSIZE也是同理;
代碼實現:
#include<stdio.h>
#include <stdlib.h>
#include<malloc.h>
#define MIXSIZE 100 //最大存儲空間
typedef struct QNode
{
int size;
int front;
int rear;
int *base;
}QNode;
//初始化
void InitQueue(QNode *Q)
{
Q->base=(int *)malloc(MIXSIZE*sizeof(int));
Q->front=Q->rear=0;
Q->size=MIXSIZE;
}
//插入
void InsertQueue(QNode *Q,int e)
{
if((Q->rear+1)%MIXSIZE==Q->front)
printf("隊列已滿\n");
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%MIXSIZE;
}
//刪除
void Pop_Queue(QNode *Q)
{
int e;
e=Q->base[Q->front++];
}
//輸入元素
void Push_Queue(QNode *Q)
{
int e;
printf("請輸入元素:\n");
for(int i=0;;i++)
{
scanf("%d",&e);
Q->base[Q->rear]=e;
Q->rear=(Q->rear+1)%MIXSIZE;
if(getchar()=='\n') //按回車鍵結束輸入
break;
}
}
//打印所以元素
void ShowQueue(QNode *Q)
{
int e;
int t=Q->front;
while(t!=Q->rear)
{
e=Q->base[t];
printf("%d ",e);
t=(t+1)%MIXSIZE;
}
printf("\n");
}
int main()
{
QNode Q,*p;
p=&Q;
InitQueue(p);
Push_Queue(p);
ShowQueue(p);
InsertQueue(p,8);
ShowQueue(p);
Pop_Queue(p);
ShowQueue(p);
}
/* 運行結果
請輸入元素:
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5 8
2 3 4 5 8
Program ended with exit code: 0
*/