C语言使用非循环双向链表实现队列
来源:互联网 发布:php 字符串截取 编辑:程序博客网 时间:2024/04/29 04:28
在前面两篇博客中,我分别使用了静态数组和动态数组来模拟循环队列。但是线性表中和队列最神似的莫过于链表了。我在前面也使用了大量的篇幅来讲述了链表的各种操作。今天我们使用一种比较特殊的链表——非循环双向链表来实现队列。首先这里的说明的是构建的是普通的队列,而不是循环队列。当我们使用数组的时候创建循环队列是为了节省存储空间,而来到链表中时,每一个节点都是动态申请和释放的,不会造成空间的浪费,所以就不需要采用循环队列了。第二,大家在很多书上看到的是使用单链表实现队列,我这里将会使用带头结点尾结点的非循环双链表实现,虽然多维护了两个节点和指针域,但是在链表头尾进行插入删除的时候不需要遍历链表了,队列操作变得非常的方便。真正实现了只在头尾操作。代码上传至https://github.com/chenyufeng1991/Queue_LinkedList 。
核心代码如下:
(1)初始化队列
//初始化带头结点和尾结点的非循环双向链表void InitialQueue(Queue **pHead,Queue **pTail){ *pHead = (Queue *)malloc(sizeof(Queue)); *pTail = (Queue *)malloc(sizeof(Queue)); if (*pHead == NULL || *pTail == NULL) { printf("%s函数执行,内存分配失败,初始化双链表失败\n",__FUNCTION__); }else{ //这个里面是关键,也是判空的重要条件 (*pHead)->next = NULL; (*pTail)->prior = NULL; //链表为空的时候把头结点和尾结点连起来 (*pHead)->prior = *pTail; (*pTail)->next = *pHead; printf("%s函数执行,带头结点和尾节点的双向非循环链表初始化成功\n",__FUNCTION__); }}
(2)入队,在尾结点插入元素
//入队,也就是在链表的尾部插入节点void EnQueue(Queue *head,Queue *tail,int x){ Queue *pInsert; pInsert = (Queue *)malloc(sizeof(Queue)); memset(pInsert, 0, sizeof(Queue)); pInsert->next = NULL; pInsert->prior = NULL; pInsert->element = x; tail->next->prior = pInsert; pInsert->next = tail->next; tail->next = pInsert; pInsert->prior = tail;}
(3)出队,在头结点处删除节点
//出队,在队列头部删除元素void DeQueue(Queue *head,Queue *tail){ if (IsEmpty(head,tail)) { printf("队列为空,出队列失败\n"); }else{ Queue *pFreeNode; pFreeNode = head->prior; head->prior->prior->next = head; head->prior = head->prior->prior; free(pFreeNode); pFreeNode = NULL; }}
(4)打印所有节点
//打印出从队列头部到尾部的所有元素void PrintQueue(Queue *head,Queue *tail){ Queue *pMove; pMove = head->prior; printf("当前队列中的元素为(从头部开始):"); while (pMove != tail) { printf("%d ",pMove->element); pMove = pMove->prior; } printf("\n");}
(5)判断队列是否为空
//判断队列是否为空,为空返回1,否则返回0int IsEmpty(Queue *head,Queue *tail){ if (head->prior == tail) { return 1; } return 0;}
(6)测试代码
int main(int argc, const char * argv[]) { Queue *pHead;//头结点 Queue *pTail;//尾结点 InitialQueue(&pHead, &pTail); EnQueue(pHead, pTail, 2);EnQueue(pHead, pTail, 1); EnQueue(pHead, pTail, 9);EnQueue(pHead, pTail, 3);EnQueue(pHead, pTail, 4); PrintQueue(pHead, pTail); DeQueue(pHead,pTail);DeQueue(pHead,pTail);DeQueue(pHead,pTail); PrintQueue(pHead, pTail); return 0;}
1 0
- C语言使用非循环双向链表实现队列
- C语言实现双向循环链表
- C语言实现双向循环链表
- C语言实现双向循环链表
- C语言实现双向循环链表
- C语言双向循环链表实现
- C语言实现双向循环链表
- c语言实现双向循环链表
- C语言实现双向非循环链表(不带头结点)的基本操作
- C语言实现双向非循环链表(不带头结点)的逆序打印
- C语言实现双向非循环链表(不带头结点)的节点插入
- C语言实现双向非循环链表(不带头结点)的清空
- C语言实现双向非循环链表(带头结点尾结点)的基本操作
- C语言实现双向非循环链表(带头结点尾结点)的节点插入
- 队列实现 (双向循环链表 C++)
- C语言 实现循环链表及双向链表
- 双向循环链表的C语言实现
- 双向循环链表实现文件C语言
- 芒果iOS开发之Apple Pay Programming Guide part3
- 如何使用Android Studio把自己的Android library分享到jCenter和Maven Central
- uva10397 最小生成树
- [leetcode 116] Populating Next Right Pointers in Each Node---层序遍历标记每一层的末尾
- 【PAT】1048. 数字加密(20)
- C语言使用非循环双向链表实现队列
- iOS开发真机调试的超简单步骤
- java语法_1:面向对象:1
- 运用Ajax和JSON对象实现JSP和Servlet的数据传递
- Ubuntu安装Sun JDK及如何设置默认java JDK
- ADS
- 二分查找算法递归和非递归实现
- 编程小练习
- PEP8 Python 编码规范