題目
假設以帶頭結點的循環鏈表表示隊列,並且只設一個指針指向隊尾結點,但不設頭指針,寫出相應的入隊列和出隊列的算法。
分析
本題是鏈隊基本操作的擴展,知道尾指針後,要實現元素入隊,則直接用鏈表的插入操作即可。要實現出隊操作,則需要根據尾指針找出頭結點和開始結點,然後進行刪除。要注意的是,尾指針應始終指向終端結點,並且當刪除結點後隊列爲空時,必須特殊處理。
代碼
核心代碼:
/* 入隊列 */
/* *&rear指的是尾指針;x指的是要插入的元素值 */
void enQueue(CLNode *&rear,int x) {
CLNode *newNode=(CLNode *)malloc(sizeof(CLNode));// 爲要入隊的結點分配空間
newNode->data=x;// 賦予數據
newNode->next=rear->next;
rear->next=newNode;// 將新結點鏈入隊尾
rear=newNode;// 將尾指針指向新結點
}
/* 出隊列 */
/* *&rear指的是尾指針;&x指的是接收出隊元素的值 */
int deQueue(CLNode *&rear,int &x) {
CLNode *tempDelNode;// 指的是要出隊的結點
if(rear->next==rear) {
return 0;
} else {
tempDelNode=rear->next->next;// 指向開始結點(第一個結點),rear->next指的是頭結點
x=tempDelNode->data;// 保存出隊元素的數據
rear->next->next=tempDelNode->next; // 將尾指針的下一個結點指向出隊結點的下一個結點
if(tempDelNode==rear) { // 如果元素出隊後隊列爲空,需要特殊處理
rear=rear->next;
}
free(tempDelNode);// 釋放結點資源
return 1;// 操作成功返回1
}
}
完整代碼:
#include <stdio.h>
#include <stdlib.h>
// 聲明循環單鏈表的結構體
struct CLNode {
int data;
struct CLNode *next;
struct CLNode *rear;// 指向隊尾結點的尾指針
};
// 創建一個循環單鏈表 */
/* *&L指的是要創建的單鏈表;a[]指的是要批量添加的整數數組;n指的是數組長度 */
void createClist(CLNode *&L,int a[],int n) {
CLNode *temp,*node;
// 創建一個帶頭結點的單鏈表
L=(CLNode *)malloc(sizeof(CLNode));
L->next=NULL;
L->rear=NULL;
temp=L; // 尾指針
for(int i=0; i<n; i++) { // 循環添加結點
node=(CLNode *)malloc(sizeof(CLNode)); // 新建結點
node->data=a[i]; // 爲結點賦數據值
temp->next=node; // 連接上新添加的結點
temp=node; // 將尾指針指向新添加的結點
}
temp->next=L; // 循環單鏈表的核心代碼。將尾指針的下一個結點指向頭結點
L->rear=temp;// 設置尾指針
}
// 打印一個循環單鏈表 */
/* *L指的是要被打印的循環單鏈表 */
void printList(CLNode *L) {
CLNode *temp;
temp=L->next;
printf("\n");
while(temp!=L) { // 循環的條件是是否等於頭指針
printf("%d\t",temp->data);
temp=temp->next;
}
printf("\n");
}
/* 入隊列 */
/* *&rear指的是尾指針;x指的是要插入的元素值 */
void enQueue(CLNode *&rear,int x) {
CLNode *newNode=(CLNode *)malloc(sizeof(CLNode));// 爲要入隊的結點分配空間
newNode->data=x;// 賦予數據
newNode->next=rear->next;
rear->next=newNode;// 將新結點鏈入隊尾
rear=newNode;// 將尾指針指向新結點
}
/* 出隊列 */
/* *&rear指的是尾指針;&x指的是接收出隊元素的值 */
int deQueue(CLNode *&rear,int &x) {
CLNode *tempDelNode;// 指的是要出隊的結點
if(rear->next==rear) {
return 0;
} else {
tempDelNode=rear->next->next;// 指向開始結點(第一個結點),rear->next指的是頭結點
x=tempDelNode->data;// 保存出隊元素的數據
rear->next->next=tempDelNode->next; // 將尾指針的下一個結點指向出隊結點的下一個結點
if(tempDelNode==rear) { // 如果元素出隊後隊列爲空,需要特殊處理
rear=rear->next;
}
free(tempDelNode);// 釋放結點資源
return 1;// 操作成功返回1
}
}
int main() {
CLNode *list,*t1,*t2;
/* [0.]創建初始測試循環單鏈表 */
int a[]= {1,3,5,7,9};
createClist(list,a,5);
/* [1.]打印循環單鏈表 */
printList(list);
enQueue(list->rear,11);// 將元素11入隊
enQueue(list->rear,22);// 將元素22入隊
enQueue(list->rear,33);// 將元素33入隊
printList(list);// 打印入隊後的鏈表
int x;
deQueue(list->rear,x);// 出隊
printf("出隊元素:%d",x);
printList(list);// 打印出隊後的鏈表
return 0;
}
運行結果: