#include <iostream>
#include "stdio.h"
#include "stdlib.h"
using namespace std;
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status;
typedef int QElemType;//因為要求是輸入整數型數據元素
//00 數據結構定義
typedef struct QNode { // 結點QNode定義
QElemType data;
struct QNode *next;
} QNode, *QueuePtr;
typedef struct { // 鏈隊LinkQueue定義
QueuePtr front; // 隊頭指針
QueuePtr rear; // 隊尾指針
} LinkQueue;
//01 初始化鏈隊Q
Status InitLQueue(LinkQueue &Q)//Q為什么加&?Q是一個有兩個指針域的結構體變量,有一個指針的值修改了,Q這個結構體變量就發生變化了。如果想讓Q返回給主函數,這個子函數就要加&。
{
Q.rear=Q.front = new QNode;
Q.front->next = NULL;//頭結點需要修改next為NULL;
return OK;0
}
//02 根據隨機輸入的隊列長度和隊列中整數型數據元素的值,創建一個非空鏈隊列;
Status CreateLQueue(LinkQueue &Q)//即使已經初始化了,但每在隊尾插入一個節點,Q的尾指針就要修改指向這個新加入的節點,故而Q發生了變化,想讓主函數同時改變,則需加&。
{
if (!Q.front)
InitLQueue(Q);
int len, n;
QueuePtr p;
cout<< "請輸入鏈隊的長度(大於0的整數):";
cin >> len;
cout << "請輸入" << len << "個整數:";
int i=0;
while (i<len)
{
cin >> n;
p = new QNode;
p->data = n;
p->next = NULL;
Q.rear->next = p;//首先,要把新結點鏈上去
Q.rear = p; //其次,修改尾指針rear指向這個新結點p
i++;
}
return OK;
}
//03 入隊
Status EnQueue(LinkQueue &Q, QElemType e)
{
QueuePtr p;
if(Q.front)
{
p = new QNode;
p->data = e;
p->next = NULL;
Q.rear->next = p;
Q.rear = p;
return OK;
}
else
{
cout << "鏈隊不存在!" <<endl;
return ERROR;
}
}
//04 出隊
Status DeQueue(LinkQueue &Q, QElemType &e)//出隊是要刪除對頭元素,如果隊中的節點大於等於2個,Q的f, r均不用修改,修改的頭結點的next域,Q沒發生變化,不用加&,但如果隊中只有一個結點出隊,則需修改Q.rear,Q發生變化了,故加&。同理e的值需要返回給主函數,故要加&。
{
if (Q.front == Q.rear)
{
printf("空鏈隊\n");
return ERROR;
}
QueuePtr p;
p = Q.front->next; //p指向隊頭元素
e = p->data;
Q.front->next = p->next; //頭結點的next指向p-next(p的后繼結點);
if (Q.rear == p)
{
Q.rear = Q.front; //如果只有一個結點,尾指針也要修改;
}
delete p;
return OK;
}
//05 判定隊列是否為空,若不空輸出隊頭元素;注意與教材上的區別,兩種不同的形式返回一個值
Status GetLQHead(LinkQueue Q, QElemType &e)//Q沒變不加,e需要返回給主函數故加&。
{
if (Q.front != Q.rear)
{
e = Q.front->next->data;
return OK;
}
else
{
printf("當前鏈隊為空,無頭元素!\n");
return ERROR;
}
}
//06 輸出鏈隊當前元素個數;
Status GetLength(LinkQueue Q, int &len)//Q沒變不加,len需要返回給主函數故加&。
{
len = 0;
if (Q.front != Q.rear)
{
QueuePtr p = Q.front->next;
while (p)
{
len++;
p = p->next;
}
}
return OK;
}
//07 輸出隊列中所有元素;
Status DisplayLQueue(LinkQueue Q)//Q沒變不加&
{
if (Q.front == Q.rear)
{
printf("空鏈隊\n");
return ERROR;
}
QueuePtr p=Q.front->next;
while (p)
{
cout << p->data << " ";
p = p->next;
}
return OK;
}
void main()
{
LinkQueue Q;
int i = InitLQueue(Q);//01初始化
printf("鏈隊始化狀態(OK-1;ERROR-0):%d\n", i);//測試鏈隊初始化是否成功,OK-1
CreateLQueue(Q);//02鏈隊的創建
printf("鏈隊從對頭到隊尾的元素是:");
DisplayLQueue(Q);
printf("\n入隊(只能在隊尾),請輸入一個整數:");
int x;
cin >> x;
EnQueue(Q, x);//03入隊
DisplayLQueue(Q);
int y;
printf("\n出隊(只能是隊頭)元素是:");
DeQueue(Q, y);//04出隊,要刪除隊頭元素
cout << y << endl;
cout << "出隊后(Q少了一個元素),鏈隊為:";
DisplayLQueue(Q);
int z;
printf("\n讀取隊頭元素:");
GetLQHead(Q, z);//05讀隊頭元素
cout << z << endl;
cout << "讀隊頭元素后(Q不變),鏈隊仍為:";
DisplayLQueue(Q);
int len;
GetLength(Q, len);//06當前鏈隊長度
cout << "\n當前鏈隊元素個數是:"<<len<<endl;
system("pause");//用於函數輸出屏幕暫停,以便觀察
}