25、队列的算法实现(链表)
数组实现的队列在出队时,每出去一个数据,其他数据就得向前移动(方法1),效率比较低,方法2中移动队首指针,但是队列空间有限,队首指针一直往后移动会出现溢出,使用链表存储,插入删除数据的时候不需要移动数据。
队列的链式存储结构,其实就是线性表的单链表,只不过它只是尾进头出而已,我们把它简称为链队列。为了操作上的方便,我们将队头指针指向链队列的头结点,而队尾指针指向终端节点。
1、链队列的初始化
#define MaxSize 5
typedef int DataType;
typedef struct _QNode{
DataType data;
struct _QNode *next;
}QNode;
typedef QNode* QueuePtr;
typedef struct Queue{
int length;
QueuePtr front;
QueuePtr rear;
}LinkQueue;
//队列的初始化、将队列初始化为空队列
void InitQueue(LinkQueue *LQ){
if(!LQ)return;
LQ->length = 0;
LQ->front = LQ->rear = NULL;//把队头和队尾指针同时置空
}
2、判断队列是否为空、队列是否已满
int IsEmpty(LinkQueue *LQ){
if(!LQ)return 0;
if(LQ->front == NULL){
return 1;
}
return 0;
}
int IsFull(LinkQueue *LQ){
if(!LQ)return 0;
if(LQ->length == MaxSize){
return 1;
}
return 0;
}
3、入队,将元素data插入到队列LQ中
int EnterQueue(LinkQueue *LQ,DataType data){
if(!LQ)return 0;
if(isFull(LQ)){
cout<<"无法插入元素"<<data<<",队列已满"<<endl;
return 0;
}
QNode *qNode = new QNode;
qNode->next = NULL;
qNode->data = data;
if(isEmpty(LQ)){//空队列插入
LQ->rear->next=qNode;//在队尾插入节点qNode
LQ->rear = qNode; //队尾指向新插入的节点
}
LQ->length++;
return 1;
}
4、出队,将队列中队头的元素出队,其后的第一个元素成为新的队首
int DeleteQueue(LinkQueue*LQ,DataType* data){
QNode *tmp = NULL;
if(!LQ || IsEmpty(LQ)){
cout<<"队列为空!"<<endl;
return 0;
}
if(!data)return 0;
tmp = LQ->front;
LQ->front = tmp->next;
if(!LQ->front)LQ->rear = NULL;//如果队头出列后不存在其他元素,则rear节点要置空
*data = tmp->data;
LQ->length--;
delete tmp;
return 1;
}
5、打印队列中的元素
void PrintQueue(LinkQueue *LQ){
QueuePtr tmp;
if(!LQ)return;
if(LQ->front ==NULL){
cout<<"队列为空!";
return;
}
tmp = LQ->front;
while(tmp){
cout<<setw(4)<<tmp->data;
tmp= tmp->next;
}
cout<<endl;
}
6、获取队首元素、不出队
int GetHead(LinkQueue *LQ,DataType *data){
if (!LQ || IsEmpty(LQ)) {
cout << "队列为空!" << endl;
return 0;
}
if (!data)return 0;
*data = LQ->front->data;
return 1;
}
7、清空队列
void ClearQueue(LinkQueue *LQ){
if(!LQ)return;
while(LQ->front){
QueuePtr tmp = LQ->front->next;
delete LQ->front;
LQ->front = tmp;
}
LQ->front = LQ->rear = NULL;
LQ->length = 0;
}
8、获取队列中的元素
int getLength(LinkQueue*LQ) {
if (!LQ)return 0;
return LQ->lenth;
}
主函数
int main(void){
LinkQueue *LQ = new LinkQueue;
DataType data = -1;
//初始化队列
InitQueue(LQ);
//入队
for(int i = 0 ; i<7;i++){
EnterQueue(LQ,i);
}
//打印队列中的元素
printf("队列中的元素(总共是%d个):",getLength(LQ));
PrintQueue(LQ);
cout<<endl;
//出队
for(int i = 0;i<10;i++){
if(DeleteQueue(LQ,&data)){
cout << "出队的元素是:" << data << endl;
}else{
cout << "出队失败!" << endl;
}
}
//打印队列中的元素
printf("出队一个元素后,队列中剩下的元素[%d]:", getLength(LQ));
PrintQueue(LQ);
cout << endl;
ClearQueue(LQ);
cout << "清空队列!\n";
PrintQueue(LQ);
//清理资源
delete LQ;
system("pause");
return 0;
}