这个用链表代替数组来实现队列
这个代码书写的时候注意ClearQueue(Link_Queue *q)
和DestroyQueue(Link_Queue *q)
这两个函数
前者在写的时候:要注意第一步是先将rear指针挪到指向队列首元素的位置,然后一举将剩下的元素一并释放,接着再释放首元素,然后使两个指针都指向头节点
后者在写的时候:要注意第一步也是先将rear指针挪到指向队列首元素的位置,但是此时是将包括首元素在内一并都释放掉。然后让两个指针都指向空。
剩下的和链表操作就差不多了,无需多费口舌
//用链式存储队列
//注意ClearQueue(Link_Queue *q) 写得很全面
#include<stdio.h>
#include<stdlib.h>
#define OK 0
#define ERROR -1
typedef int Status;
typedef int QElemType;
//链表上链的每一个结构
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
//链表本身
typedef struct
{
QueuePtr front;
QueuePtr rear;
}Link_Queue;
Status
InitQueue(Link_Queue * q)
{
//创建一个头节点和一个头指针
q->front = (QueuePtr)malloc(sizeof(QNode));
if(q->front == NULL)
//return ERROR;
exit(ERROR);
q->rear = q->front;
q->front->next = NULL;
return OK;
}
Status
DestroyQueue(Link_Queue *q)
{
//free(q);
//这考虑的也太navie了
while(q->front)
{
q->rear = q->front->next;
free(q->front);
q->front = q->rear;
}
return OK;
}
//巧妙
Status
ClearQueue(Link_Queue *q)
{
// if(q->front != q->rear)
// q->front --;
// q->front->next = NULL;
q->rear = q->front->next;//先保存一下
while(q->rear)
{
q->front->next = q->rear->next;
free(q->rear);
q->rear = q->front->next;
}
q->rear = q->front;
return OK;
}
Status
QueueEmpty(Link_Queue q)
{
if(q.front == q.rear)
return OK;
else
return ERROR;
}
int
QueueLength(Link_Queue q)
{
int count = 0;
QueuePtr p = q.front;
while(p != q.rear)
{
count++;
p=p->next;
}
return count;
//return q.rear - q.front;
//this have a little question
//算不算上头节点呢,是用头减尾还是尾减头呢?
}
Status
GetHead(Link_Queue q,QElemType *e)
{
*e = q.front->next->data;
return OK;
}
Status
EnQueue(Link_Queue *q,QElemType e)
{
QueuePtr temp;
temp = (QueuePtr)malloc(sizeof(QNode));
if(temp == NULL)
//return ERROR;
exit(ERROR);
temp->data = e;
//temp = q->front;
// while( temp != q->rear) //这里有尾指针啊大哥
// {
// temp = temp->next;
// }
//q->rear->next = temp;
temp->next = NULL;
q->rear->next = temp;
q->rear = temp;
//最后要把为指针改变一下
return OK;
}
Status
DeQueue(Link_Queue *q,QElemType *e)
{
if( q->front == q->rear ) return ERROR;
//删除的时候要把原来的保存一下,好释放空间
QueuePtr temp;
temp = q->front->next;
*e = temp->data;
q->front->next = temp->next;
//当删除最后一个元素时需要注意⚠️此时队尾指针丢了
if(q->rear == temp)
q->rear = q->front;
free(temp);
//q->front->next = q->front->next->next;
return OK;
}
Status
QueueTraverse(Link_Queue q,void(*visit)(QElemType ))
{
if( q.front == q.rear ) return ERROR;
while(q.front != q.rear)
{
q.front = q.front->next;
visit(q.front->data);
}
printf("\n");
return OK;
}
void
visit(QElemType c)
{
printf("%d ", c);
}
int main(int argc, char const *argv[])
{
Link_Queue q;
QElemType delete,length;
InitQueue(&q);
EnQueue(&q,1);
EnQueue(&q,2);
EnQueue(&q,3);
EnQueue(&q,4);
GetHead(q,&delete);
printf("top is %d ", delete);
printf("\nAfter insert: ");
QueueTraverse(q,visit);
length = QueueLength(q);
printf("queue length is %d \n", length);
DeQueue(&q,&delete);
printf("\ndelete %d is ok!\n", delete);
printf("\nAfter delete: ");
QueueTraverse(q,visit);
length = QueueLength(q);
printf("queue length is %d \n", length);
printf("\n");
return 0;
}