数据结构队列的链式存储(c语言描述)
队列是一种先进先出的线性表,在表头进行出队列,在表尾入队列,看了很多的队列的文章,发现每个人写的方式都不一样,但是最终都会遵从先进先出这个特性
1.定义结构体
typedef int ElemType; //队列是一种先进先出线性表 typedef struct QNode{ ElemType data; struct QNode *next;//指向下一个元素 }QNode,*QueuePtr; typedef struct{ QueuePtr front,rear;//指向队头,队尾的指针 }QueuePointer;
2.初始化链队列:队头和队尾指针都指向头结点,但是他们的指针域都为空
void initQueue(QueuePointer *q) { q->front=q->rear=(QNode *)malloc(sizeof(QNode)); //指针指向的是同一块动态空间 if(!q->front) { printf("初始化空间失败\n"); } q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 }
3.入队操作
void push(QueuePointer *q,ElemType e) { QNode *currentNode=(QNode*)malloc(sizeof(QNode));//动态生成结点 if(!currentNode) { printf("申请空间失败\n"); } currentNode->data=e; currentNode->next=NULL; //因为在队列尾部入队,队列尾部的指针域为空 q->rear->next=currentNode; //和队尾连接起来 q->rear=currentNode; //队尾指针重新指向队尾 }
4.出队列操作
//出队列操作 ElemType pop(QueuePointer *q,ElemType *e) { if(q->front==q->rear) { printf("队列为空,无法出队列\n"); return -1; } else if(q->front->next==q->rear)//队列中只有一个元素 { *e=q->rear->data; free(q->rear); //释放空间,避免内存泄漏 q->rear=q->front; //头尾指针都指向头结点, q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 return *e; } else //队列中的元素不止一个 { *e=q->front->next->data; QueuePtr temp=q->front->next; q->front->next=temp->next; free(temp); //释放空间,避免内存泄漏 return *e; } }
5.销毁队列操作
void destroyQueue(QueuePointer *q) { QueuePtr temp,currentNode; currentNode=q->front->next; //从第一个元素结点开始 while(currentNode)//当队列不为空时 { temp=currentNode->next; free(currentNode); currentNode=temp; } q->rear=q->front; //头尾指针都指向头结点, q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 }
6.输出当前队列
void printfQueue(QueuePointer q) { QueuePtr temp=q.front->next;//获取第一个有元素的结点 while(temp) { printf("%d ",temp->data); temp=temp->next; } printf("\n"); }
所有的代码如下:
#include<stdio.h> #include<stdlib.h> typedef int ElemType; //队列是一种先进先出线性表 typedef struct QNode{ ElemType data; struct QNode *next;//指向下一个元素 }QNode,*QueuePtr; typedef struct{ QueuePtr front,rear;//指向队头,队尾的指针 }QueuePointer; //初始化链式队列 void initQueue(QueuePointer *q) { q->front=q->rear=(QNode *)malloc(sizeof(QNode)); //指针指向的是同一块动态空间 if(!q->front) { printf("初始化空间失败\n"); } q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 } //入队操作 void push(QueuePointer *q,ElemType e) { QNode *currentNode=(QNode*)malloc(sizeof(QNode));//动态生成结点 if(!currentNode) { printf("申请空间失败\n"); } currentNode->data=e; currentNode->next=NULL; //因为在队列尾部入队,队列尾部的指针域为空 q->rear->next=currentNode; //和队尾连接起来 q->rear=currentNode; //队尾指针重新指向队尾 } //出队列操作 ElemType pop(QueuePointer *q,ElemType *e) { if(q->front==q->rear) { printf("队列为空,无法出队列\n"); return -1; } else if(q->front->next==q->rear)//队列中只有一个元素 { *e=q->rear->data; free(q->rear); //释放空间,避免内存泄漏 q->rear=q->front; //头尾指针都指向头结点, q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 return *e; } else //队列中的元素不止一个 { *e=q->front->next->data; QueuePtr temp=q->front->next; q->front->next=temp->next; free(temp); //释放空间,避免内存泄漏 return *e; } } //销毁队列操作 void destroyQueue(QueuePointer *q) { QueuePtr temp,currentNode; currentNode=q->front->next; //从第一个元素结点开始 while(currentNode)//当队列不为空时 { temp=currentNode->next; free(currentNode); currentNode=temp; } q->rear=q->front; //头尾指针都指向头结点, q->front->next=q->rear->next=NULL;//头尾指针都指向头结点,但是指针域为空 } //输出当前队列 void printfQueue(QueuePointer q) { QueuePtr temp=q.front->next;//获取第一个有元素的结点 while(temp) { printf("%d ",temp->data); temp=temp->next; } printf("\n"); } int main() { QueuePointer q;//声明结构体对象 int number;//指令 int e; // 数据 initQueue(&q);//初始化 printf("结束操作----------0\n"); printf("入队列操作----------1\n"); printf("出队列操作----------2\n"); printf("销毁队列操作----------3\n"); printf("打印操作----------4\n"); printf("请输入你的指令:"); scanf("%d",&number); while(number!=0) { switch(number) { case 1: printf("请输入要入队列的值:"); scanf("%d",&e); push(&q,e); break; case 2: e=pop(&q,&e); printf("出队列的值为:%d\n",e); break; case 3: destroyQueue(&q); printf("队列已销毁"); case 4: printfQueue(q); break; default: printf("你输入的指令不正确\n"); } printf("你的指令为:"); scanf("%d",&number); } return 0; }
队列的链式操作就是这样了,记录日常。