考研數據結構之隊列(3.3)——練習題之假設以帶頭結點的循環鏈表表示隊列,並且只設一個指針指向隊尾結點,但不設頭指針,寫出相應的入隊列和出隊列的算法(C表示)

題目

假設以帶頭結點的循環鏈表表示隊列,並且只設一個指針指向隊尾結點,但不設頭指針,寫出相應的入隊列和出隊列的算法。

分析

本題是鏈隊基本操作的擴展,知道尾指針後,要實現元素入隊,則直接用鏈表的插入操作即可。要實現出隊操作,則需要根據尾指針找出頭結點和開始結點,然後進行刪除。要注意的是,尾指針應始終指向終端結點,並且當刪除結點後隊列爲空時,必須特殊處理。

代碼

核心代碼:

/* 入隊列 */
/* *&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;
}

運行結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章