資料結構與演算法實驗1——線性表的應用之棧與佇列

每天八杯水D發表於2020-11-29

線性表的應用之棧與佇列

一、目的要求
1.掌握棧、佇列的思想及其儲存實現。
2.掌握棧、佇列的常見演算法的程式實現
二、實驗內容
1.採用鏈式儲存實現棧的初始化、入棧、出棧操作。
2.採用順序儲存實現棧的初始化、入棧、出棧操作。
3.採用鏈式儲存實現佇列的初始化、入隊、出隊操作。
4.採用順序儲存實現迴圈佇列的初始化、入隊、出隊操作。
5.在主函式中設計一個簡單選單,呼叫上述演算法
三、實驗說明
1.順序棧型別定義
const int MAX=20 ; // 棧的最大值
typedef struct
{
ElemType *base;
int top;
} SqStack;
2. 順序佇列型別定義
const int MAX=20 ; // 佇列的最大長度
typedef struct
{
ElemType *base;
int front,rear;
} SqQueue;
四、程式碼
(一)標頭檔案

#pragma once
#include<iostream>
#include<stdlib.h>
using namespace std;

//順序棧型別定義
const int MAX1 = 20; // 棧的最大值
typedef int ElemType;//元素型別
typedef struct Node
{
	ElemType* base;//存放元素的起始指標
	int top;//棧頂
} SqStack;//型別名
typedef SqStack* SeqStack;//定義SeqStack為指向結構體型別的指標

//鏈式棧型別定義
typedef int DataType;
typedef struct LNode
{
	DataType data;
	struct LNode* next;
};
typedef struct LNode* LinkStack;

//順序佇列型別定義
const int MAX2 = 20; // 佇列的最大長度
typedef struct PNode
{
	ElemType* base;//指標代表陣列首地址
	int front;
	int rear;//首指標,尾指標用數值表示
};
typedef struct PNode* SqQueue;

//鏈式佇列型別定義
typedef int DataType;
struct Node1
{
	DataType data;
	struct Node1* next;
};
typedef struct Node1* KNode;
struct Queue
{
	KNode f;//隊頭指標
	KNode r;//隊尾指標
};
typedef struct Queue* LinkQueue;

/*
	順序棧操作
*/
SeqStack SetStack_Seq()//建立順序棧
{
	SeqStack sstack = (SeqStack)malloc(sizeof(SqStack));//申請結構體空間
	sstack->base = (ElemType*)malloc(sizeof(ElemType) * MAX1);//元素空間,以陣列表示
	cout << "請輸入元素以520結束:";
	int data;
	cin >> data;
	sstack->top = -1;//top為棧頂,以第一個元素top為0開始計算
	int i = 0;
	while (data!=520)
	{
	
		sstack->base[i] = data;//賦值
		i++;
		sstack->top++;//棧頂元素下標加1
		cin >> data;
	}
	return sstack;
}
void ShowStack(SeqStack sstack)
{
	cout << "遍歷順序棧:";
	for (int i = 0; i <= sstack->top; i++)
	{
		cout << sstack->base[i]<<"  ";
	}

}
SeqStack Push_Seq(SeqStack sstack, int x)//輸入一個元素進棧
{
	sstack->top++;//棧頂下標加1
	sstack->base[sstack->top] = x;
	return sstack;
}
SeqStack Pop_Seq(SeqStack sstack)//出棧
{
	sstack->top= sstack->top-1;//棧頂下標減1
	return sstack;
}
/*
	鏈式棧操作
*/
LinkStack SetLink_Stack()//鏈式棧初始化
{
	LinkStack top = (LinkStack)malloc(sizeof(struct LNode));//相當於頭結點
	if (top != NULL)//非常重要,如果沒有這一步,就會出現棧底指標域就不為空
		top->next = NULL;
	cout << "請輸入元素:";
	int data;
	cin >> data;
	while (data!=520)
	{
		LinkStack PNode = (LinkStack)malloc(sizeof(struct LNode));//建立的元素結點

		PNode->data = data;
		PNode->next = top->next;//前插法
		top->next = PNode;
		cin >> data;
	}
	return top;
}
LinkStack Push_Link(LinkStack top, int x)//進棧-相當於單連結串列的插入
{
	LinkStack q= (LinkStack)malloc(sizeof(struct LNode));//建立進棧元素結點
	q->data = x;
	q->next = top->next;
	top->next = q;
	return top;
}
LinkStack Pop_Link(LinkStack top)//出棧-相當於單連結串列的刪除
{
	LinkStack q;
	q = top->next;
	top->next = q->next;
	free(q);
	return top;
}
void ShowLinkStack(LinkStack top)//遍歷連結串列
{
	LinkStack q;
	cout << "遍歷鏈式棧:";
		for (q=top->next ; q ;q=q->next)
		{
			cout << q->data << "  ";
		}
}
/*
	順序佇列操作
*/
SqQueue SetQueue()//輸入元素建立迴圈順序佇列
{
	SqQueue squeue = (SqQueue)malloc(sizeof(struct PNode));
	squeue->front = 0;
	squeue->rear = 0;
	squeue->base = (ElemType*)malloc(sizeof(ElemType) * MAX2);//存放元素陣列的首地址指標
	cout << "請輸入元素建立順序佇列:";
	int data;
	cin >> data;
	int i = 0;
	while (data!=520)
	{
		squeue->base[i] = data;
		i++;
		squeue->rear = ((squeue->rear + 1) % (MAX2));//每增加一個元素,尾指標後移一位,當尾指標為max2時,rear又等於0,回到起點開始迴圈
		cin >> data;//尾指標rear始終比i大1
	}
	return squeue;
}
SqQueue Push_Queue(SqQueue squeue,int x)//進隊
{
	squeue->base[squeue->rear ] = x;
	squeue->rear = ((squeue->rear + 1) % (MAX2));
	return squeue;
}
SqQueue Pop_Queue(SqQueue squeue)//出隊
{
	squeue->front = (squeue->front+1) % MAX2;//首指標加1
	return squeue;
}
void ShowQueue(SqQueue squeue)
{
	int temp = squeue->front;//下面squeue->front會自增,要保持其值防止下次呼叫此函式squeue->front是上一次的值
	cout << "遍歷順序迴圈佇列為:";
	for (squeue->front; squeue->front < squeue->rear; squeue->front++)
	{
		cout << squeue->base[squeue->front]<<"  ";

	}
	squeue->front = temp;
}
/*
	鏈式佇列操作
*/
LinkQueue SetLink_Queue()//建立鏈式佇列
{
	LinkQueue lqueue = (LinkQueue)malloc(sizeof(struct Queue));//含有隊頭隊尾的指標的接單
	if (lqueue != NULL)
	{
		lqueue->f = NULL;
		lqueue->r = NULL;
	}
	cout << "請輸入元素建立鏈式佇列:";
	int data;
	cin >> data;
	while (data!=520)
	{
		KNode p=(KNode)malloc(sizeof(struct Node1));
		p->data = data;
		p->next = NULL;
		if (lqueue->f == NULL)//第一個結點特殊處理
		{
			lqueue->f = p;
			lqueue->r = p;
		}
		else//從第二個開始把尾指標指向新節點p
		{
			lqueue->r->next = p;
			lqueue->r = p;
		}
		cin >> data;
	}
	return lqueue;
}
LinkQueue  EnQueue_link(LinkQueue lqueue,int x)//進佇列,從尾指標進相當於單連結串列尾部插入元素
{
	KNode q=(KNode)malloc(sizeof(struct Node1));
	q->data = x;
	q->next = NULL;
	lqueue->r->next = q;
	lqueue->r = q;
	return lqueue;
}
LinkQueue	DeQueue_link(LinkQueue lqueue)//出隊,從頭指標刪除
{
	KNode q;
	q = lqueue->f;
	lqueue->f = lqueue->f->next;
	free(q);
	return lqueue;
}
void ShowLink_Queue(LinkQueue lqueue)
{
	KNode q;
	cout << "遍歷鏈式佇列:";
	for (q=lqueue->f;q;q=q->next)
	{
		cout << q->data << "  ";
	}
}

(二)原始檔

/*
實驗名稱:棧與佇列
實驗目的:
	1.掌握棧、佇列的思想及其儲存實現。
	2.掌握棧、佇列的常見演算法的程式實現。
實驗內容:
	1.採用鏈式儲存實現棧的初始化、入棧、出棧操作。
	2.採用順序儲存實現棧的初始化、入棧、出棧操作。
	3.採用鏈式儲存實現佇列的初始化、入隊、出隊操作。
	4.採用順序儲存實現迴圈佇列的初始化、入隊、出隊操作。
	5.在主函式中設計一個簡單選單,呼叫上述演算法。
實驗日期:2020/11/28
開發者:每天八杯水
*/
#include<iostream>
#include"棧與佇列.h";
using namespace std;
int Out1();//子選單
/*
	順序棧操作
*/
SeqStack SetStack_Seq();
SeqStack Push_Seq();//型別為SeqStack是返回指標讓showstack遍歷
SeqStack Pop_Seq();
void ShowStack();
/*
	鏈式棧操作
*/
LinkStack SetLink_Stack();
LinkStack Push_Link();
LinkStack Pop_Link();
void ShowLinkStack();

/*
	順序佇列操作
*/
SqQueue SetQueue();
SqQueue Push_Queue();
SqQueue Pop_Queue();
void ShowQueue();

/*
	鏈式佇列操作
*/
LinkQueue SetLink_Queue();//建立鏈式佇列
LinkQueue  EnQueue_link();
LinkQueue	DeQueue_link();
void ShowLink_Queue();

int main()
{
	/*
		主選單介面
		我設定了一個主選單四個子選單介面
		實現方法:
			1.使用了兩個switch進行使用者輸入不同數字進入不同介面
			2.使用迴圈while判斷條件為true或false,true則繼續顯示選單介面,false則退出此選單,若在子選單false則退出返回到主選單
	*/
	bool opt = true;
	while (opt == true)
	{
		cout << "\n\t\t*****************************"<<endl;
		cout << "\t\t*     1 順序儲存實現棧      *" << endl;
		cout << "\t\t*     2 鏈式儲存實現棧      *" << endl;
		cout << "\t\t*     3 順序儲存實現佇列    *" << endl;
		cout << "\t\t*     4 鏈式儲存實現佇列    *" << endl;
		cout << "\t\t*     5     退 出           *";
		cout << "\n\t\t*****************************" << endl;
		cout << "\t\t請選擇:";
			int a;
			cin >> a;
			switch (a)
			{
				case 1:
				{
					cout << "你選擇了順序儲存實現棧" << endl;
						/*
							進入順序棧介面
						*/
						cout << "\n\t\t**************************" << endl;
						cout << "\t\t* 歡迎您來到順序棧的世界 *" << endl;
						cout << "\t\t*  請輸入元素建立順序棧  *" << endl;
						cout << "\t\t**************************" << endl;
						//開始建立順序棧
						SeqStack sstack;
						sstack = SetStack_Seq();//建立順序棧
						ShowStack(sstack);//遍歷
					bool opt1 = true;//順序棧操作子選單判斷
					while (opt1 == true)
					{
						//建立棧後可選擇的操作
						cout << "\n\t\t**************************" << endl;
						cout << "\t\t*       請您選擇操作     *" << endl;
						cout << "\t\t*        1 進棧          *" << endl;
						cout << "\t\t*        2 出棧          *" << endl;
						cout << "\t\t*        3 返回主選單    *" << endl;
						cout << "\t\t**************************" << endl;
						cout << "\t\t請選擇操作:";
						int c;
						cin >> c;
						switch (c)
						{
						case 1://進棧操作
							cout << "請輸入進棧的元素:";
							int x;
							cin >> x;
							ShowStack(Push_Seq(sstack, x));
							opt1 =Out1();//為true返回子選單,為false退出子選單迴圈返回主選單
							break;

						case 2://出棧操作
							ShowStack(Pop_Seq(sstack));
							opt1 = Out1();
							break;
	
						case 3://返回主選單
							opt1 =false;
							break;
						default:
							cout << "非法輸入,請重新輸入!" << endl;
							break;
						}
					}
					opt =true;
				}
					break;
				case 2:
				{
					cout << "你選擇了鏈式儲存實現棧" << endl;
					/*
						進入鏈式棧介面
					*/
					cout << "\n\t\t**************************" << endl;
					cout << "\t\t* 歡迎您來到鏈式棧的世界 *" << endl;
					cout << "\t\t*  請輸入元素建立鏈式棧  *" << endl;
					cout << "\t\t**************************" << endl;
					//開始建立鏈式棧
					LinkStack LStack;
					LStack= SetLink_Stack();//建立鏈式棧
					ShowLinkStack(LStack);//遍歷
					bool opt1 = true;//鏈式棧操作子選單判斷
					while (opt1 == true)
					{
						//建立棧後可選擇的操作
						cout << "\n\t\t**************************" << endl;
						cout << "\t\t*       請您選擇操作     *" << endl;
						cout << "\t\t*        1 進棧          *" << endl;
						cout << "\t\t*        2 出棧          *" << endl;
						cout << "\t\t*        3 返回主選單    *" << endl;
						cout << "\t\t**************************" << endl;
						cout << "\t\t請選擇操作:";
						int c;
						cin >> c;
						switch (c)
						{
						case 1://進棧操作
							cout << "請輸入進棧的元素:";
							int x;
							cin >> x;
							ShowLinkStack(Push_Link(LStack, x));
							opt1 = Out1();//為true返回子選單,為false退出子選單迴圈返回主選單
							break;

						case 2://出棧操作
							ShowLinkStack(Pop_Link(LStack));
							opt1 = Out1();
							break;

						case 3://返回主選單
							opt1 = false;
							break;
						default:
							cout << "非法輸入,請重新輸入!" << endl;
							break;
						}
					}
					opt = true;
				}
				break;
				case 3:
				{
					cout << "你選擇了順序儲存實現佇列" << endl;
					/*
						進入順序棧介面
					*/
					cout << "\n\t\t***************************" << endl;
					cout << "\t\t* 歡迎您來到順序佇列的世界 *" << endl;
					cout << "\t\t*  請輸入元素建立順序佇列  *" << endl;
					cout << "\t\t***************************" << endl;
					//開始建立順序佇列
					SqQueue squeue;
					squeue = SetQueue();//建立順序佇列
					ShowQueue(squeue);//遍歷
					bool opt1 = true;//順序佇列操作子選單判斷
					while (opt1 == true)
					{
						//建立佇列後可選擇的操作
						cout << "\n\t\t**************************" << endl;
						cout << "\t\t*       請您選擇操作     *" << endl;
						cout << "\t\t*        1 進隊          *" << endl;
						cout << "\t\t*        2 出隊         *" << endl;
						cout << "\t\t*        3 返回主選單    *" << endl;
						cout << "\t\t**************************" << endl;
						cout << "\t\t請選擇操作:";
						int c;
						cin >> c;
						switch (c)
						{
						case 1://進隊操作
							cout << "請輸入進隊的元素:";
							int x;
							cin >> x;						
							ShowQueue(Push_Queue(squeue, x));
							opt1 = Out1();//為true返回子選單,為false退出子選單迴圈返回主選單
							break;

						case 2://出隊操作
							ShowQueue(Pop_Queue(squeue));						
							opt1 = Out1();
							break;

						case 3://返回主選單
							opt1 = false;
							break;
						default:
							cout << "非法輸入,請重新輸入!" << endl;
							break;
						}
					}
					opt = true;
				}
				break;
				case 4:
				{
					cout << "你選擇了鏈式儲存實現佇列" << endl;
					/*
						進入鏈式佇列介面
					*/
					cout << "\n\t\t***************************" << endl;
					cout << "\t\t* 歡迎您來到鏈式佇列的世界 *" << endl;
					cout << "\t\t*  請輸入元素建立鏈式佇列  *" << endl;
					cout << "\t\t***************************" << endl;
					//開始建立鏈式佇列
					LinkQueue lqueue;
					lqueue = SetLink_Queue();//建立鏈式佇列
					ShowLink_Queue(lqueue);//遍歷
					bool opt1 = true;//鏈式佇列操作子選單判斷
					while (opt1 == true)
					{
						//建立佇列後可選擇的操作
						cout << "\n\t\t**************************" << endl;
						cout << "\t\t*       請您選擇操作     *" << endl;
						cout << "\t\t*        1 進對          *" << endl;
						cout << "\t\t*        2 出隊          *" << endl;
						cout << "\t\t*        3 返回主選單    *" << endl;
						cout << "\t\t**************************" << endl;
						cout << "\t\t請選擇操作:";
						int c;
						cin >> c;
						switch (c)
						{
						case 1://進隊操作
							cout << "請輸入進隊的元素:";
							int x;
							cin >> x;
							ShowLink_Queue(EnQueue_link(lqueue, x));
							opt1 = Out1();//為true返回子選單,為false退出子選單迴圈返回主選單
							break;

						case 2://出隊操作
							ShowLink_Queue(DeQueue_link(lqueue));

							opt1 = Out1();
							break;

						case 3://返回主選單
							opt1 = false;
							break;
						default:
							cout << "非法輸入,請重新輸入!" << endl;
							break;
						}
					}
					opt = true;
				}
				break;
				case 5://退出整個程式
					cout << "你選擇了退出程式" << endl;
					opt =false;
					break;
				default:
					cout << "\t\t非法輸入,請重新輸入!" << endl;
					break;
				}
			}
		cout << "選單已退出" << endl;
	
}

/*
	每當一個操作執行完後使用者可選擇回上一層繼續操作還是回主選單選擇其他儲存結構
*/
int Out1()
{
	cout << "\n\t\t*****************" << endl;
	cout << "\t\t*  1 返回子選單  *" << endl;
	cout << "\t\t*  2 返回主選單  *" ;
	cout << "\n\t\t*****************" << endl;
	cout << "\t\t請選擇:";
	int b;
	cin >> b;
	switch (b)
	{
	case 1:
		return true;
		break;
	case 2:
		return false;
		break;
	default:
		cout << "\t\t非法輸入,請重新輸入!";
		return true;
		break;
	}
}

(三)執行截圖


                *****************************
                *     1 順序儲存實現棧      *
                *     2 鏈式儲存實現棧      *
                *     3 順序儲存實現佇列    *
                *     4 鏈式儲存實現佇列    *
                *     5     退 出           *
                *****************************
                請選擇:1
你選擇了順序儲存實現棧

                **************************
                * 歡迎您來到順序棧的世界 *
                *  請輸入元素建立順序棧  *
                **************************
請輸入元素以520結束:1 2 3 4 520
遍歷順序棧:1  2  3  4
                **************************
                *       請您選擇操作     *
                *        1 進棧          *
                *        2 出棧          *
                *        3 返回主選單    *
                **************************
                請選擇操作:2
遍歷順序棧:1  2  3
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:1

                **************************
                *       請您選擇操作     *
                *        1 進棧          *
                *        2 出棧          *
                *        3 返回主選單    *
                **************************
                請選擇操作:1
請輸入進棧的元素:5201314
遍歷順序棧:1  2  3  5201314
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:2

                *****************************
                *     1 順序儲存實現棧      *
                *     2 鏈式儲存實現棧      *
                *     3 順序儲存實現佇列    *
                *     4 鏈式儲存實現佇列    *
                *     5     退 出           *
                *****************************
                請選擇:2
你選擇了鏈式儲存實現棧

                **************************
                * 歡迎您來到鏈式棧的世界 *
                *  請輸入元素建立鏈式棧  *
                **************************
請輸入元素:9 8 7 6 5 4 520
遍歷鏈式棧:4  5  6  7  8  9
                **************************
                *       請您選擇操作     *
                *        1 進棧          *
                *        2 出棧          *
                *        3 返回主選單    *
                **************************
                請選擇操作:1
請輸入進棧的元素:5201314
遍歷鏈式棧:5201314  4  5  6  7  8  9
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:1

                **************************
                *       請您選擇操作     *
                *        1 進棧          *
                *        2 出棧          *
                *        3 返回主選單    *
                **************************
                請選擇操作:2
遍歷鏈式棧:4  5  6  7  8  9
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:2

                *****************************
                *     1 順序儲存實現棧      *
                *     2 鏈式儲存實現棧      *
                *     3 順序儲存實現佇列    *
                *     4 鏈式儲存實現佇列    *
                *     5     退 出           *
                *****************************
                請選擇:3
你選擇了順序儲存實現佇列

                ***************************
                * 歡迎您來到順序佇列的世界 *
                *  請輸入元素建立順序佇列  *
                ***************************
請輸入元素建立順序佇列:11 22 33 44 520
遍歷順序迴圈佇列為:11  22  33  44
                **************************
                *       請您選擇操作     *
                *        1 進隊          *
                *        2 出隊         *
                *        3 返回主選單    *
                **************************
                請選擇操作:2
遍歷順序迴圈佇列為:22  33  44
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:1

                **************************
                *       請您選擇操作     *
                *        1 進隊          *
                *        2 出隊         *
                *        3 返回主選單    *
                **************************
                請選擇操作:5201314
非法輸入,請重新輸入!

                **************************
                *       請您選擇操作     *
                *        1 進隊          *
                *        2 出隊         *
                *        3 返回主選單    *
                **************************
                請選擇操作:1
請輸入進隊的元素:5201314
遍歷順序迴圈佇列為:22  33  44  5201314
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:2

                *****************************
                *     1 順序儲存實現棧      *
                *     2 鏈式儲存實現棧      *
                *     3 順序儲存實現佇列    *
                *     4 鏈式儲存實現佇列    *
                *     5     退 出           *
                *****************************
                請選擇:4
你選擇了鏈式儲存實現佇列

                ***************************
                * 歡迎您來到鏈式佇列的世界 *
                *  請輸入元素建立鏈式佇列  *
                ***************************
請輸入元素建立鏈式佇列:01 02 03 04 05 06 520
遍歷鏈式佇列:1  2  3  4  5  6
                **************************
                *       請您選擇操作     *
                *        1 進對          *
                *        2 出隊          *
                *        3 返回主選單    *
                **************************
                請選擇操作: 2
遍歷鏈式佇列:2  3  4  5  6
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:1

                **************************
                *       請您選擇操作     *
                *        1 進對          *
                *        2 出隊          *
                *        3 返回主選單    *
                **************************
                請選擇操作:1
請輸入進隊的元素:5201314
遍歷鏈式佇列:2  3  4  5  6  5201314
                *****************
                *  1 返回子選單  *
                *  2 返回主選單  *
                *****************
                請選擇:2

                *****************************
                *     1 順序儲存實現棧      *
                *     2 鏈式儲存實現棧      *
                *     3 順序儲存實現佇列    *
                *     4 鏈式儲存實現佇列    *
                *     5     退 出           *
                *****************************
                請選擇:5
你選擇了退出程式
選單已退出

A:\3-資料結構與演算法\實驗\上機實驗報告\實驗1:線性表的應用\棧與佇列\Debug\棧與佇列.exe (程式 20844)已退出,程式碼為 0。
要在除錯停止時自動關閉控制檯,請啟用“工具”->“選項”->“除錯”->“除錯停止時自動關閉控制檯”。
按任意鍵關閉此視窗. . .

五、思考總結
1.對於棧與佇列的理解加深了,這是第二次敲棧與佇列,熟悉了原理,查缺補漏,第一遍不理解的地方也疏通了
2.我的理解棧與佇列就是順序表和單連結串列的特殊處理;比如順序棧——本質就是順序表,只不過我們規定了它只能從尾巴進尾巴出,程式碼實現改變了一下。再者鏈式佇列——相當於單連結串列的特殊處理,進隊出隊本質就是單連結串列的插入和刪除,只是程式碼規定了只能從尾巴插入就是最後一個元素後面插入,只能從第一個元素刪除稱為出隊。鏈式棧和順序佇列同理,這樣更容易理解一點
3.自此我的資料結構與演算法實驗1——線性表的應用一共四個應用:順序表、單向連結串列、雙向連結串列、棧與佇列都完成了一共歷時一週,很開心,因延期回校復學晚了的情況下終於把這門課程進度趕上了,下週就要開始實驗2了——二叉樹的應用,加油加油加油奧利給!

在這裡插入圖片描述
謝謝您的瀏覽,由於水平有限,很多地方有待提高,若您有更好的建議歡迎留言!————————————每天八杯水

相關文章