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

简介

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



实现分析

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


}

实现结果:




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值