数据结构-单链表模拟实现循环队列(c语言实现)

Posted 许同学。。

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-单链表模拟实现循环队列(c语言实现)相关的知识,希望对你有一定的参考价值。

1.类型声明

typedef struct CQueue {
	struct SLnode* front;
	struct SLnode* tail;
}CQueue;

typedef struct SLnode {
	int date;
	struct SLnode*next;
} SLnode;

2.创造节点

SLnode* BuySLnode() {
	SLnode*node = (SLnode*)malloc(sizeof(SLnode));
    if(node==NULL)
       {
          printf("Failed to open up capacity");
       }
	node->date = 0;
	node->next = NULL;
	return node;
}

3.类型声明


CQueue* CQueueInit(int k) 
{
	CQueue*pq= (CQueue*)malloc(sizeof(CQueue));
	if (pq == NULL)
	{
		printf("Failed to open up capacity");
	}
	SLnode*plist = BuySLnode();
	SLnode*p = plist;
	for (int i = 0; i < k; i++)
	{
		p->next = BuySLnode();
		p = p->next;
	}
	p->next = plist;
	p = NULL;//不用指针p了置空
	pq->front = pq->tail = plist;
	return pq;
}

构成一个循环单链表,使CQueue->tail与CQueue->front指向循环单链表的第一个节点,如果根据所需申请空间 判空与判满无法判断,所以需要多申请一个空间(不存放数据)

4. 判空

int CQueueIsEmpty(CQueue* pq) 
{
	return pq->front == pq->tail ? 1 : 0;
}

5.判满

int CQueueIsFull(CQueue* pq)
{
	SLnode*tailnext = pq->tail->next;
	return tailnext == pq->front ? 1 : 0;
}

6.入队

void  CQueuePush(CQueue* pq, int value) 
{
	if (CQueueIsFull(pq))
	{
		return;
	}
	else
	{
		pq->tail->date = value;
		pq->tail = pq->tail->next;;
	}
}

7.出队

void CQueuePop(CQueue* pq) 
{
	if (CQueueIsEmpty(pq))
	{
		return ;
	}
	else
	{
		pq->front = pq->front->next;
	}
}

8.获取队首的数据

int CQueueFront(CQueue* pq) 
{
	if (CQueueIsEmpty(pq))
	{
		return -1;
	}
	return pq->front->date;
}

如果是空队的话,返回一个-1。

9.获取队尾的数据

int CQueueTail(CQueue* pq) 
{
	if (CQueueIsEmpty(pq))
	{
		return -1;
	}
	SLnode*cur = pq->front;
	while (cur->next != pq->tail)
	{
		cur = cur->next;
	}
	return cur->date;
}

获取队尾的数据,是需要找到tail前一个位置。而不是return tail->date 

10.队列的长度

int CQueueLength(CQueue*pq)
{
	SLnode*cur = pq->front;
	int size = 0;
	while (cur != pq->tail)
	{
		cur = cur->next;
		++size;
	}
	return size;
}

11.打印(为了更好的测试各个接口)

void Print(CQueue*pq)
{
	SLnode*cur = pq->front;
	while (cur != pq->tail)
	{
		printf("%2d", cur->date);
		cur = cur->next;
	}
	printf("\\n");
}

11.置空

void CQueueDestory(CQueue* pq) 
{
	SLnode*cur = pq->front;
	while (cur != pq->tail)
	{
		SLnode*next = cur->next;
		free(cur);
		cur = next;
	}
	free(cur);
	pq->front = pq->tail = NULL;
	free(pq);
	pq = NULL;
}

注意这里传的是一级指针。

12.测试

test()
{
	//测试入队
	CQueue*cq = CQueueInit(5);
	CQueuePush(cq, 2);
	CQueuePush(cq, 3);
	CQueuePush(cq, 4);
	CQueuePush(cq, 5);
	CQueuePush(cq, 6);
	CQueuePush(cq, 7);
	Print(cq);

	//测试出队
	CQueuePop(cq);
	CQueuePop(cq);
	Print(cq);

	//获取对头的数据
	printf("%2d\\n", CQueueFront(cq));

	//获取对尾的数据
	printf("%2d\\n", CQueueTail(cq));

	//队列的长度,即有效数据的个数
	printf("%2d\\n", CQueueLength(cq));

	//再次打印
	Print(cq);

	//释放空间
	CQueueDestory(cq);
	cq = NULL;
}

由于传的是一级指针 ,在CQueueDestory中,即使free(pq)了,但是在主函数Queue*cq会成为野指针,所以需要将cq=NULL.

13.测试结果

 

 

 

单链表的模拟实现循环队列的基本操作就分享到这里了,感谢你的浏览。如果对你有帮助的话,可以给赞,顺便点个关注。

 下期将发布有关与双向链表的基本操作的文章。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

以上是关于数据结构-单链表模拟实现循环队列(c语言实现)的主要内容,如果未能解决你的问题,请参考以下文章

如何用c语言实现单链表的逆置?

数据结构C语言版 —— 链表增删改查实现(单链表+循环双向链表)

基于C语言的队列实现

基于C语言的队列实现

基于C语言的队列实现

C语言队列