C语言:数据结构之队列

队列:生活中也会经常遇到的场景。即只允许在一端进行数据的插入操作,另一端进行数据的删除操作的特殊线性表。
插入的一端一般为队尾(即为入队);删除的一端则为队首(即出队)。具有 先进先出(FIFO)的特性。
在这儿,我写了2种队列:顺序队和链式队。
先来说说顺序队:出队的方法:①队头不变,出队后所有元素向前移动;②不移动元素,每删除一个元素,队头就向后移动一个元素。
①队头位置不变:如下图所示:
缺点:如果元素数量很多时,就要大批大批的移动数据。
②队头位置不变:
缺点:删除元素后,原来对头的位置就会浪费。并且再有元素入队时,就会发生溢出现象。
结合这两种删除所带来的麻烦,所以就有了循环队列。即不会大量的移动元素,也不会发生溢出现象,不会浪费空间。
如下图所示:判队空
缺点:虽然循环队列对于前面的两种有所提高,但是当插入的元素大于最大的队列个数是依然会溢出。
下面是顺序队的代码实现:

#pragma once

#define TEST_HEADER printf("\n==================%s================\n",__FUNCTION__)

typedef char QueueType;

#define MaxQueue 1000     //定义队最大可以容纳1000个元素

typedef struct SeqQueue
{
	QueueType data[MaxQueue];
	size_t head;
	size_t tail;
	size_t size;
}SeqQueue;

SeqQueue q;

void SeqQueueInit(SeqQueue* q);//初始化队列

void SeqQueueDestroy(SeqQueue* q); //销毁队列

void SeqQueuePush(SeqQueue* q,QueueType value);//入队

void SeqQueuePop(SeqQueue* q);//出队

int SeqQueueTop(SeqQueue* q,QueueType* top);//找队首元素

#include<stdio.h>
#include"seqqueue.h"

void SeqQueueInit(SeqQueue* q)
{
	if(q == NULL)
	{
		//非法输入
		return;
	}
	q->head = 0;
	q->tail = 0;
	q->size = 0;
}
void SeqQueueDestroy(SeqQueue* q)
{
	if(q == NULL)
	{
		//非法输入
		return;
	}
	q->head = 0;
	q->tail = 0;
	q->size = 0;
}
void SeqQueuePush(SeqQueue* q,QueueType value)
{
	if(q == NULL)
	{
		//非法输入
		return;
	}
	if(q->size >= MaxQueue)
	{
		return;
	}
	if(q->head == 0)
	{
		q->head = q->tail = value;
	}
	q->data [q->tail ++] = value;
	++q->size ;
	if(q->tail >= MaxQueue)
	{
		q->tail = 0;
	}
}
void SeqQueuePop(SeqQueue* q)
{
	if(q == NULL)
	{
		return;
	}
	if(q->head == 0)
	{
		//空队列
		return;
	}
	++q->head ;
	if(q->head >= MaxQueue)
	{
		q->head = 0;
	}
}
int SeqQueueTop(SeqQueue* q,QueueType* top)
{
	if(q == NULL)
	{
		return 0;
	}
	if(q->head == 0)
	{
		return 0;
	}
	*top = q->data [q->head ];
	return 1;
}

#include<stdio.h>
#include"seqqueue.h"
void TEST_SeqQueue()
{
	QueueType temp = 0;
	TEST_HEADER;
	SeqQueueInit(&q);
	SeqQueuePush(&q,'a');
	SeqQueuePush(&q,'b');
	SeqQueuePush(&q,'c');
	SeqQueuePush(&q,'d');
	SeqQueueTop(&q,&temp);
	printf("top expect is a ,actual is %c\n",temp);
	SeqQueuePop(&q);

	SeqQueueTop(&q,&temp);
	printf("top expect is b ,actual is %c\n",temp);
	SeqQueuePop(&q);

	SeqQueueTop(&q,&temp);
	printf("top expect is c ,actual is %c\n",temp);
	SeqQueuePop(&q);

	SeqQueueTop(&q,&temp);
	printf("top expect is d ,actual is %c\n",temp);
	SeqQueuePop(&q);
}
//////////////////test/////////////////////
int main()
{
	TEST_SeqQueue();
	return 0;
}

当循序队中元素的个数大于定义的队的最大元素时就会溢出,但是链式队是不会存在这个问题的。
下面是链式队:
#pragma once

#define TEST_HEADER printf("\n===============%s============\n",__FUNCTION__)

typedef char QueueNodeType;

typedef struct LinkQueueNode
{
	struct LinkQueueNode* next;
	QueueNodeType data;
}LinkQueueNode;

typedef struct LinkQueue
{
	LinkQueueNode* head;
	LinkQueueNode* tail;
}LinkQueue;

LinkQueue q;

void LinkQueueInit(LinkQueue* q);

void LinkQueuePush(LinkQueue* q,QueueNodeType value);

void LinkQueuePop(LinkQueue* q);

int LinkQueueTop(LinkQueue* q,QueueNodeType* top);
#include<stdio.h>
#include"LinkQueue.h"
#include<stdio.h>
#include<stdlib.h>
void LinkQueueInit(LinkQueue* q)
{
	if(q == NULL)
	{
		//非法输入
		return;
	}
	q->head = NULL;
	q->tail = NULL;
}
LinkQueueNode* CreateLinkNode(QueueNodeType value)
{
	LinkQueueNode* new_node = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
	new_node->data = value;
	new_node->next = NULL;
	return new_node;
}
void LinkQueuePush(LinkQueue* q,QueueNodeType value)
{
	LinkQueueNode* new_node = NULL;
	if(q == NULL)
	{
		return;
	}
	new_node = CreateLinkNode(value);
	if(q->head == NULL)
	{
		q->head = q->tail = new_node;
		return;
	}
	q->tail->next = new_node;
	q->tail = q->tail ->next;
}
void DestroyNode(LinkQueueNode* ptr)
{
	free(ptr);
}
void LinkQueuePop(LinkQueue* q)
{
	LinkQueueNode* to_deleted = NULL;
	if(q == NULL)
	{
		//非法输入
		return;
	}
	if(q->head == NULL)
	{
		//空队列
		return;
	}
	to_deleted = q->head ;
	if(q->head == q->tail )
	{
		DestroyNode(to_deleted);
		q->head = q->tail = NULL;
		return;
	}
	q->head = to_deleted->next;
	DestroyNode(to_deleted);
}
int LinkQueueTop(LinkQueue* q,QueueNodeType* top)
{
	if(q == NULL || top == NULL)
	{
		return 0;
	}
	if(q->head == NULL)
	{
		return 0;
	}
	*top = q->head->data ;
	return 1;
}

#include"LinkQueue.h"
#include<stdio.h>
void TEST_LinkQueue()
{
	QueueNodeType tmp = 0;
	TEST_HEADER;
	LinkQueueInit(&q);
	LinkQueuePush(&q,'a');
	LinkQueuePush(&q,'b');
	LinkQueuePush(&q,'c');
	LinkQueuePush(&q,'d');

	LinkQueueTop(&q,&tmp);
	printf("expect is a,actual is %c\n",tmp);
	LinkQueuePop(&q);

	LinkQueueTop(&q,&tmp);
	printf("expect is b,actual is %c\n",tmp);
	LinkQueuePop(&q);

	LinkQueueTop(&q,&tmp);
	printf("expect is c,actual is %c\n",tmp);
	LinkQueuePop(&q);

	LinkQueueTop(&q,&tmp);
	printf("expect is d,actual is %c\n",tmp);
	LinkQueuePop(&q);
}
int main()
{
	TEST_LinkQueue();
	return 0;
}


猜你喜欢

转载自blog.csdn.net/yinghuhu333333/article/details/79480591