c語言:用雙向鏈表實現雙端隊列(隊列兩端都可以進行入隊出隊操作)

//雙端隊列的實現:隊列左爲端口1,隊列右爲端口2
#include<iostream>
#include<stdio.h>
#include<math.h>
#define LEN sizeof(struct DQueuelist)
using namespace std;
typedef struct DQueuelist    //定義結構體結點
{
	int data;                //結構體數據域
	struct DQueuelist *prior; //結構體前向指針
	struct DQueuelist *next;  //結構體後向指針
}DQueuelist, *DQueueptr;
typedef struct                //定義雙端隊列
{
	DQueueptr front;         //頭指針,指向鏈隊列頭結點
	DQueueptr rear;          //尾指針,指向鏈隊列最後一個結點
}LinkDQueue;
//函數聲明部分
void Error(char *s);
LinkDQueue Creat_DQueuelist();              //錯誤處理函數
void En_DQueuelist(LinkDQueue &q, int e);    //創建雙端隊列函數
void De_DQueuelist(LinkDQueue &q, int e);    //入隊函數
void Print_DQueuelist(LinkDQueue &q);        //出隊函數
int Getlength_DQueuelist(LinkDQueue &q);     //計算雙端隊列長度函數
void Gethead_DQueuelist(LinkDQueue &q, int e); //得到雙端隊列的端口處的元素
void Destroy_DQueuelist(LinkDQueue &q);      //銷燬雙端隊列函數

//函數定義定義
void Error(char *s)
{
	cout << s << endl;
	exit(1);
}
LinkDQueue Creat_DQueuelist()  //創建雙端隊列
{
	DQueuelist *pnew;      //初始化雙端隊列
	LinkDQueue head;
	head.front = head.rear = (struct DQueuelist *)malloc(LEN);  //創建頭結點
	head.front->data = 0;  
	head.front->next = NULL;
	head.rear->next = NULL;
	int length = 0;
	int number = 0;
	cout << "請輸入雙端隊列長度:";
	cin >> length;
	cout << "請輸入雙端隊列數據:";
	for (int i = 0; i < length; i++) //端口2創建雙端隊列
	{
		pnew = (struct DQueuelist *)malloc(LEN);
		if (!pnew)
			Error("內存分配失敗!");
		cin >> number;
		pnew->data = number;
		pnew->next = NULL;
		head.rear->next = pnew;
		pnew->prior = head.rear;
		head.rear = pnew;
	}
	return head;
}
void En_DQueuelist(LinkDQueue &q, int e)  //入隊函數
{//1表示在端口1入隊,2表示在端口2入隊
	int a;
	DQueuelist *ptr = NULL;
	DQueuelist *temp = NULL;
	cout << "請選擇入隊端口(默認端口爲1和2):";
	cin >> a;
	switch (a)
	{
	case 1:
		ptr = (struct DQueuelist *)malloc(LEN);//端口1入隊只改變隊頭指針,不改變隊尾指針,
		                                      //且將結點插入到頭結點之後,使其成爲第一個結點
		                                        
		if (!ptr)
			Error("內存分配失敗!");
		ptr->data = e;
		temp = q.front->next;
		q.front->next = ptr;
		ptr->next = temp;
		temp->prior = ptr;
		ptr->prior = q.front;
		break;
	case 2:
		ptr = (struct DQueuelist *)malloc(LEN); //端口2入隊只改變隊尾指針,不改變隊頭指針
		                                        //將該結點直接插入到最後面即可
		if (!ptr)
			Error("內存分配失敗!");
		ptr->data = e;
		ptr->next = NULL;
		q.rear->next = ptr;
		ptr->prior = q.rear;
		q.rear = ptr;
		break;
	}
}
void De_DQueuelist(LinkDQueue &q, int e)  //出隊函數
{//1表示在端口1出隊,2表示在端口2出隊
	int a;
	cout << "請輸入出隊端口(默認端口爲1和2):";
	cin >> a;
	DQueuelist *ptr = NULL;
	DQueuelist *temp = NULL;
	switch (a)
	{
	case 1://端口1出隊,將頭結點後的第一個結點刪除即可,改變頭指針,不改變尾指針
		if (q.front->next == NULL)
			Error("該隊列爲空!");
		ptr = q.front->next;
		e = ptr->data;
		cout << "端口1出隊的元素是:" << e << endl;
		q.front->next = ptr->next;
		ptr->next->prior = q.front;
		if (q.rear == ptr)
			q.rear = q.front;
		delete ptr;
		break;
	case 2://端口2出隊,直接將最後一個結點刪除即可,改變尾指針,不改變頭指針
		if (q.rear == NULL)
			Error("該隊列爲空!");
		ptr = q.rear->prior;
		temp = q.rear;
		e = temp->data;
		cout << "端口2出隊的元素是:" << e << endl;
		ptr->next = NULL;
		q.rear = ptr;
		if (q.front == ptr)
			q.front = q.rear;
		delete temp;
		break;
	}
}
void Print_DQueuelist(LinkDQueue &q) //輸出函數
{
	int e = 0;
	int n = 0;
	cout << "請輸入順序出隊端口:";
	cin >> n;
	switch (n)
	{
	case 1:  //端口1順序輸出,正向輸出
		while (q.front->next != NULL)
		{
			DQueuelist *p = NULL;
			p = q.front->next;
			e = p->data;
			cout << e << " ";
			q.front->next = p->next;
			//p->next->prior = q.rear;
			if (q.rear == p)
				q.rear = q.front;
		}
		cout << endl;
		break;
	case 2://端口2順序輸出,逆向輸出
		while ((q.rear != NULL)&&(q.rear->data!=0))
		{
			DQueuelist *p = NULL;
			DQueuelist *temp = NULL;
			p = q.rear->prior;
			temp = q.rear;
			e = temp->data;
			cout << e << " ";
			p->next = NULL;
			q.rear = p;
			if (q.front == p)
				q.rear = q.front;
		}
		cout << endl;
		break;
	}
}
int Getlength_DQueuelist(LinkDQueue &q) //計算雙端隊列長度函數
{
	DQueuelist *p = NULL;
	p = q.front;
	int length = 0;
	while (p->next != NULL)
	{
		length++;
		p = p->next;
	}
	return length;
}
void Gethead_DQueuelist(LinkDQueue &q, int e) //得到雙端隊列的端口處的元素,並不修改指針頭和尾,只是簡單的輸出而已
{//1表示得到雙端隊列端口1的元素,2表示得到雙端隊列斷口2的元素
	cout << "請輸入出隊端口:";
	int a = 0;
	cin >> a;
	switch (a)
	{
	case 1:
		if (q.front->next == NULL) //判斷頭結點之後一個節點是否爲空
			Error("該隊列爲空!");
		e = q.front->next->data;
		cout << "端口1的第一個元素是:" << e << endl;
		break;
	case 2:
		if (q.rear == NULL) //判斷最後一個結點是否爲空
			Error("該隊列爲空!");
		e = q.rear->data;
		cout << "端口2的第一個元素是:" << e << endl;
		break;
	}
}
void Destroy_DQueuelist(LinkDQueue &q)  //銷燬函數
{
	while (q.front)
	{
		q.rear = q.front->next;
		delete q.front;
		q.front = q.rear;
	}
	cout << "該鏈隊列銷燬成功!" << endl;
}

int main()
{
	LinkDQueue Q;
	Q = Creat_DQueuelist();
	cout << "該雙端隊列的長度是:" << Getlength_DQueuelist(Q) << endl;
	int m = 0;
	for (int i = 0; i < 2; i++)
	{
		int n = 0;
		cout << "請輸入要入隊的元素:";
		cin >> n;
		En_DQueuelist(Q, n);
	}
	cout << "入隊後雙端隊列的長度是:" << Getlength_DQueuelist(Q) << endl;
	for (int j = 0; j < 2; j++)
	{
		De_DQueuelist(Q, m);
	}
	cout << "出隊後雙端隊列的長度是:" << Getlength_DQueuelist(Q) << endl;
	Print_DQueuelist(Q);
	Destroy_DQueuelist(Q);
	return 0;
}

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