【筆記】鏈式佇列
阿新 • • 發佈:2018-12-25
一、鏈式佇列的表示
1.鏈式佇列
用連結串列表示的佇列,簡稱為鏈佇列。鏈式佇列在插入和刪除過程中不需要移動大量的元素,只需要改變指標的位置即可。
一個鏈式佇列顯然需要兩個分別指示隊頭和隊尾的指標(分別稱為頭指標和尾指標)才能唯一確定。空的鏈佇列的判決條件為頭指標和尾指標均指向頭結點。
2.鏈式迴圈佇列
將鏈式佇列的首尾相連就構成了鏈式迴圈佇列。在鏈式迴圈佇列中,可以只設置隊尾指標。當佇列為空時,判斷條件為LQ.rear->next==LQ.rear。
二、鏈式佇列的實現
題目:判斷任意給定的字元序列是否為迴文。
分析:可以通過構造棧和佇列實現。可先把一個字元序列分別存入佇列和棧,然後將字元出佇列和出棧,比較出佇列的字元和出棧的字元是否相等,若相等則繼續出佇列和棧中的下一個字元進行比較,直到棧和佇列為空,表明該字元序列為迴文;若有字元不相等,則該字元序列不是迴文。
- 型別定義
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<malloc.h>
typedef char DataType; /*資料型別為字元型別*/
/*鏈式堆疊結點型別定義*/
typedef struct snode
{
DataType data;
struct snode *next;
}LSNode;
/*只有隊尾指標的鏈式迴圈佇列型別定義*/
typedef struct QNode
{
DataType data;
struct QNode *next;
}LQNode,*LinkQueue;
- 棧的函式
void InitStack(LSNode **head)
/*帶頭結點的鏈式堆疊初始化*/
{
if((*head=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*為頭結點分配空間*/
{
printf("分配結點不成功");
exit(-1);
}
else
(*head)->next=NULL; /*頭結點的指標域設定為空*/
}
int StackEmpty(LSNode * head)
/*判斷帶頭結點鏈式堆疊是否為空。如果堆疊為空,返回1,否則返回0*/
{
if(head->next==NULL) /*如果堆疊為空,返回1,否則返回0*/
return 1;
else
return 0;
}
int PushStack(LSNode *head,DataType e)
/*鏈式堆疊進棧。進棧成功返回1,否則退出*/
{
LSNode *s;
if((s=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*為結點分配空間,失敗退出程式並返回-1*/
exit(-1);
else
{
s->data=e; /*把元素值賦值給結點的資料域*/
s->next=head->next; /*將結點插入到棧頂*/
head->next=s;
return 1;
}
}
int PopStack(LSNode *head,DataType *e)
/*鏈式堆疊出棧,需要判斷堆疊是否為空。出棧成功返回1,否則返回0*/
{
LSNode *s=head->next; /*指標s指向棧頂結點*/
if(StackEmpty(head)) /*判斷堆疊是否為空*/
return 0;
else
{
head->next=s->next; /*頭結點的指標指向第二個結點位置*/
*e=s->data; /*要出棧的結點元素賦值給e*/
free(s); /*釋放要出棧的結點空間*/
return 1;
}
}
- 初始化佇列
void InitStack(LSNode **head)
/*帶頭結點的鏈式堆疊初始化*/
{
if((*head=(LSNode*)malloc(sizeof(LSNode)))==NULL)/*為頭結點分配空間*/
{
printf("分配結點不成功");
exit(-1);
}
else
(*head)->next=NULL; /*頭結點的指標域設定為空*/
}
- 獲取佇列狀態
void InitQueue(LinkQueue *rear)
/*將帶頭結點的鏈式迴圈佇列初始化為空佇列,需要把頭結點的指標指向頭結點*/
{
if((*rear=(LQNode*)malloc(sizeof(LQNode)))==NULL)
exit(-1); /*如果申請結點空間失敗退出*/
else
(*rear)->next=*rear; /*隊尾指標指向頭結點*/
}
int QueueEmpty(LinkQueue rear)
/*判斷鏈式佇列是否為空,佇列為空返回1,否則返回0*/
{
if(rear->next==rear) /*判斷佇列是否為空。當佇列為空時,返回1,否則返回0*/
return 1;
else
return 0;
}
- 入隊操作
int EnQueue(LinkQueue *rear,DataType e)
/*將元素e插入到鏈式佇列中,插入成功返回1*/
{
LQNode *s;
s=(LQNode*)malloc(sizeof(LQNode)); /*為將要入隊的元素申請一個結點的空間*/
if(!s) exit(-1); /*如果申請空間失敗,則退出並返回引數-1*/
s->data=e; /*將元素值賦值給結點的資料域*/
s->next=(*rear)->next; /*將新結點插入鏈式佇列*/
(*rear)->next=s;
*rear=s; /*修改隊尾指標*/
return 1;
}
- 出隊操作
int DeQueue(LinkQueue *rear,DataType *e)
/*刪除鏈式佇列中的隊頭元素,並將該元素賦值給e,刪除成功返回1,否則返回0*/
{
LQNode *f,*p;
if(*rear==(*rear)->next) /*在刪除隊頭元素即出佇列之前,判斷鏈式佇列是否為空*/
return 0;
else
{
f=(*rear)->next; /*使指標f指向頭結點*/
p=f->next; /*使指標p指向要刪除的結點*/
if(p==*rear) /*處理佇列中只有一個結點的情況*/
{
*rear=(*rear)->next;/*使指標rear指向頭結點*/
(*rear)->next=*rear;
}
else
f->next=p->next; /*使頭結點指向要出佇列的下一個結點*/
*e=p->data; /*把隊頭元素值賦值給e*/
free(p); /*釋放指標p指向的結點*/
return 1;
}
}
- 主程式
int DeQueue(LinkQueue *rear,DataType *e)
/*刪除鏈式佇列中的隊頭元素,並將該元素賦值給e,刪除成功返回1,否則返回0*/
{
LQNode *f,*p;
if(*rear==(*rear)->next) /*在刪除隊頭元素即出佇列之前,判斷鏈式佇列是否為空*/
return 0;
else
{
f=(*rear)->next; /*使指標f指向頭結點*/
p=f->next; /*使指標p指向要刪除的結點*/
if(p==*rear) /*處理佇列中只有一個結點的情況*/
{
*rear=(*rear)->next;/*使指標rear指向頭結點*/
(*rear)->next=*rear;
}
else
f->next=p->next; /*使頭結點指向要出佇列的下一個結點*/
*e=p->data; /*把隊頭元素值賦值給e*/
free(p); /*釋放指標p指向的結點*/
return 1;
}
}
- 測試結果