数据结构-队列(C语言)

队列

先进先出,后进后出的思想
允许在一端插入数据,允许在另外一端删除数据
队尾rear:允许插入数据的一端
对头front:允许删除数据的一端

实现这个队列的时候有两种方式
顺序队列:
使用的就是数组实现的
我们实现这个顺序队列的时候有一点点小问题
我们不管是入队还是出队,rear 和 front实际上是不会减小的
他们是一直在增大,而我们的内存又是有限的
这个时候就会出现一种可能,你的队列里面的元素个数没有到上限
但是rear这一端可能会到达极限,达到它的最大的下标位置
这个时候我们叫队列的假溢出
元素个数到达最大值之后你还要往里面加入元素,这个东西我们叫真溢出

为了防止假溢出,我们一般做的顺序队列都是循环队列
当我们的rear front达到最大值之后,发现你的元素
个数还没有到上限,我们让这两个玩意儿回去,继续入队
这样才能防止假溢出
栈是没有假溢出的

链式队列:
使用的就是单链表

队列也需要实现如下操作
	1 初始化一个队列 		QueueInit
	2 销毁队列				QueueDestory
	3 清空队列				QueueClear
	4 判断这个队列是否为空	QueueIsEmpty
	5 返回队列里面多少个元素 QueueGetLength
	6 返回对头元素,不出队	QueueGetFront
	7 入队					InQueue
	8 出队					OutQueue	
typedef int ElemType;
#define  QueueErro  INT32_MIN
#define QueueMax 1024
typedef struct QueueNode
{
    
    
	ElemType data;
	struct QueueNode* next;

}Node;

typedef struct QueueHead
{
    
    
	struct QueueNode* front; //队头
	struct QueueNode* rear;  //队尾
	int num;
	int MaxNum;
}Head;

实现队列出队入队

//初始化队列
Head* QueueInit(int MaxNum)
{
    
    
	if (MaxNum > 1024 || MaxNum <= 0)
	{
    
    
		MaxNum == 1024;

	}
	Head* q = malloc(sizeof(Head));

	q->front = q->rear = NULL;
	q->num = 0;
	q->MaxNum = MaxNum;
	
	return q;
}

//建立一个队列节点
//初始化节点
static Node* QueueCreateNode(const ElemType data)
{
    
    
	Node* pnew = malloc(sizeof(Node));
	pnew->data = data;
	pnew->next = NULL;

	return pnew;
}

//判断为空
bool QueueIsEmpty(Head* q)
{
    
    
	if (!q || QueueGetLength(q) == 0)
	{
    
    
		return true;
	}
	else
	{
    
    
		return false;
	}
}

//队内多少个元素
int QueueGetLength(Head* q)
{
    
    
	if (!q)
	{
    
    
		return -1;
	}
	return q->num;
}


//返回队头元素,不出队
ElemType QueueReturn(Head* q)
{
    
    
	if (!q || !q->front)
	{
    
    
		return QueueErro;

	}
	else
	{
    
    
		return q->front->data;
	}
}

//入队
void InQueue(Head * q,ElemType data)
{
    
    
	if (!q)
	{
    
    
		printf("队列不存在,不能入队\n");
		return;
	}
	if (QueueGetLength(q) >= q->MaxNum)
	{
    
    
		printf("队列满了,不能入队\n");
		return;

	}

	Node* pnew = QueueCreateNode(data);
	//队列中没有元素
	if (QueueIsEmpty(q))
	{
    
    
		
		q->front = q->rear = pnew;
	}
	else
	{
    
    
		q->rear->next = pnew;
		q->rear = pnew;
		
	}
	q->num++;
}


//出队
ElemType OutQueue(Head* q)
{
    
    
	if (!q)
	{
    
    
		printf("队列不存在,无法出队\n");
		return QueueErro;
	}
	if (QueueGetLength(q) == 0)
	{
    
    
		printf("队列没有元素,无法出队\n");
		return QueueErro; 
	}

	Node* p = q->front;
	ElemType data = q->front->data;

	if (QueueGetLength(q) == 1)
	{
    
    
		q->front = q->rear = NULL;

	}
	else
	{
    
    
		
		q->front = q->front->next;
		
		p->next = NULL;
	}
	free(p);
	q->num--;
	return data;
}

队列的销毁和清空

//销毁
void QueueDestory(Head** q)
{
    
    
	if (!q || !(*q))
	{
    
    
		return;
	}

	QueueClear(*q);
	free(*q);
	*q = NULL;
}

//清空
void QueueClear(Head* q)
{
    
    
	if (!q)
	{
    
    
		return;
	}

	while (!QueueIsEmpty(q))
	{
    
    
		OutQueue(q);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_46836491/article/details/125944288