队列的两种存储方式的介绍与实现(后续)

来源:互联网 发布:淘宝双11活动入口 编辑:程序博客网 时间:2024/05/22 20:21

简介

队列分为顺序存储结构和链式存储结构,链式存储结构其实就是线性表的单链表,只是只能在对头出元素,队尾进元素而已。从之前实现的队列的顺序存储结构中
我们可以看到他的缺点,我们为了避免“假溢出”就实现循环队列的顺序结构,但是循环队列必须指定出队列的长度,所以说它并不完美。当然我们就可以用链式存储结构
的方式来弥补上述的不足。



实现分析

链表是有一个个节点连接而成,每个节点就是一个结构体(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;}

实现结果: