您的位置:首页 > 编程语言 > C语言/C++

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

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;

}


实现结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息