队列的两种存储方式的介绍与实现(后续)
2017-08-02 14:06
381 查看
简介
队列分为顺序存储结构和链式存储结构,链式存储结构其实就是线性表的单链表,只是只能在对头出元素,队尾进元素而已。从之前实现的队列的顺序存储结构中我们可以看到他的缺点,我们为了避免“假溢出”就实现循环队列的顺序结构,但是循环队列必须指定出队列的长度,所以说它并不完美。当然我们就可以用链式存储结构
的方式来弥补上述的不足。
实现分析
链表是有一个个节点连接而成,每个节点就是一个结构体(value和next指针组成),当然我们得为整个链表创建头指针(front)和尾指针(rear)的指针域.我们的头指针中并不存放数据,只是存放一个指向对头的节点地址,尾指针(rear)指向链表的队尾。当头指针(front)==尾指针(rear)时,就可以简单的实现队空的情况。
如下图所示:
接下来我们来实现该结构的增删查等功能,先看一个图:
/*链式存储结构 *每个节点包含:一个值、一个指向下一个节点的指针 *链表结构:由头指针、尾指针组成一个指针域 *采用链式存储结构的队列和顺序存储结构区别: *链式存储结构头指针指向的节点中并不存放数据,只是指向队头。 */ typedef struct QueNode{ QueType value; struct QueNode *next; }qNode,*qNodePtr; typedef struct { qNodePtr front; qNodePtr rear; }LinkQueue ; //初始化 int InitLinkQueue(LinkQueue *que){ qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间 pNode = (qNodePtr)malloc(sizeof(qNode)); que->front = que->rear = pNode; //初始化 return 0; } //判空 int LinkQueueEmpty(LinkQueue *que){ if(que->front == que->rear){ printf("队列为空\n"); return 0; } return -1; } //增加节点 int EnLinkQueueValue(LinkQueue *que ,QueType Ele){ qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间 pNode = (qNodePtr)malloc(sizeof(qNode)); pNode->value = Ele; pNode->next = NULL; que->rear->next = pNode; que->rear = pNode;//将尾指针指向新插的节点 return 0; } //删除节点 int DeLinkQueueValue(LinkQueue * que ,QueType * Ele ){ if(LinkQueueEmpty(que)==0){ printf("删除节点失败\n"); return -1; } //队列中存在有效的节点 qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间 //将头指针指向的下一个节点地址赋给pNode节点 pNode = que->front->next; *Ele = pNode->value;//将要删除的节点值赋值给Ele //将头指针指向pNode的下一个位置 que->front->next = pNode->next; free(pNode);//释放内存。 return 0; } //链表中节点个数 int getLinkQueueSize(LinkQueue *que){ int size = 0; qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间 pNode = (qNodePtr)malloc(sizeof(qNode)); if(LinkQueueEmpty(que)==0){ printf("链表中不存在元素\n"); return 0; } pNode = que->front->next; while(pNode){ size ++; pNode = pNode->next; } free(pNode); return size; } //遍历链表数据 int showLinkQueueList(LinkQueue *que){ if(LinkQueueEmpty(que)==0){ printf("链表中不存在元素\n"); return -1; } qNodePtr pNode;//创建一个节点结构指针,分配一个临时空间 pNode = (qNodePtr)malloc(sizeof(qNode)); pNode = que->front->next; printf("节点数据为\n"); while(pNode){ printf("【%d】\n",pNode->value); pNode = pNode->next; } free(pNode); return 0; }
测试代码:
//测试 int main( void){ int ret = 0,size=0; //增加节点 QueType Ele1 = 1; QueType Ele2 = 2; QueType Ele3 = 3; LinkQueue *que; que = (LinkQueue *)malloc(sizeof(LinkQueue)); //初始化 InitLinkQueue(que); ret = EnLinkQueueValue(que ,Ele1); if(ret){ printf("新增节点1失败\n"); } ret = EnLinkQueueValue(que ,Ele2); if(ret){ printf("新增节点2失败\n"); } ret = EnLinkQueueValue(que ,Ele3); if(ret){ printf("新增节点3失败\n"); } //节点个数 size = getLinkQueueSize(que); printf("此时的链表节点个数为【%d】\n",size); //删除一个节点 QueType *Ele = NULL ; QueType ele ; Ele = (QueType*)malloc(sizeof(QueType)); ret = DeLinkQueueValue(que,Ele); if(ret){ printf("删除节点失败\n"); } ele = *Ele; //删除后的节点个数 size = getLinkQueueSize(que); printf("删除后的节点个数为【%d】\n",size); printf("删除的节点value为【%d】\n",ele); //遍历 showLinkQueueList(que); free(Ele); return 0; }
实现结果:
相关文章推荐
- 队列的两种存储方式的介绍与实现
- Web APi之认证(Authentication)两种实现方式后续【三】(十五)
- Java队列的两种实现方式
- Java可阻塞队列的两种实现方式 (传统wait/notify和jdk1.5以后的lock)
- 安装php扩展pthreads实现PHP多线程 原创qw871122015-04-16 17:01评论(0)948人阅读 下面介绍两种编译方式: 1、在已有的PHP上编译pthreads扩展 注:需
- 实现动态代理的两种方式介绍+例子demo(JDK、CGlib)
- prim算法构造最小生成树(邻接表和数组两种存储方式实现)
- 大话数据结构(六)——队列的两种java实现方式
- Java可阻塞队列的两种实现方式
- [LeetCode] Binary Tree Level Order Traversal 与 Binary Tree Zigzag Level Order Traversal,两种按层次遍历树的方式,分别两个队列,两个栈实现
- 思维导图实现——栈的两种存储方式优缺点
- Java实现阻塞队列的两种方式
- 双队列的两种实现方式
- 队列的C++实现(两种方式)
- [置顶] rabbitmq 实现延迟队列的两种方式
- 【Flask】Flask实现密码存储安全性的两种方式
- 队列的链式存储方式的实现(Java语言描述)
- Web APi之认证(Authentication)两种实现方式后续【三】
- 队列的链式存储方式的实现(Java语言描述)
- 队列的链式存储的两种定义方式