数据结构---链队的实现


目录

  • 链队---队列的链式表示和实现
  • 链队列的结构定义
  • 链队列的基本操作
  • 1.初始化---构造一个只有头结点的空队列
  • 2.清空队列---让队列重置成初始化的状态(头结点还存在,指针域为空)
  • 3.销毁队列---整个队列不再存在(需释放头结点)
  • 4.入队
  • 5.出队
  • 6.取队头元素
  • 7.判断队列是否为空
  • 8.求队列长度

链队---队列的链式表示和实现

链队是指采用链式存储结构实现的队列。结点删除移动头指针,结点添加移动尾指针,具有先进先出的特点

头指针---头结点 尾指针---尾结点

链队列的结构定义

typedef struct QNode
{
QElemType data; //队列元素
struct QNode *next;//指向下一元素结点
}QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //队头指针
QueuePtr rear;//队尾指针
} LinkQueue;

链队列的基本操作

1.初始化---构造一个只有头结点的空队列

算法步骤

  • 生成新结点作为头结点, 队头和队尾指针指向此结点。
  • 头结点的指针域置空。

算法实现

void InitQueue(LinkQueue &Q) 
{
	QNode *QHead = new QNode;//构建头结点
	Q.rear = Q.front = QHead; //初始头指针和尾指针,指向头结点
	Q.front->next = Q.rear->next = NULL;//在使用前把指针域设置为NULL
}
2.清空队列---让队列重置成初始化的状态(头结点还存在,指针域为空)

算法步骤

  • 将头尾指针都指向头结点
  • 依次清空头结点后面结点的指针域和数据域

算法实现

void ClearQueue(LinkQueue &Q)
{
	Q.rear = Q.front; //初始化为头尾都指向同一处(头结点)
	QueuePtr p,q;//设置变量来进行指针的移动
	p = Q.front->next;//p指向头结点下一结点
	Q.front->next = NULL;//将头结点指针域置空
	while(p) {
		q = p;
		free(q);
		p = p->next;//p指针向后移动
	}
}
3.销毁队列---整个队列不再存在(需释放头结点)

算法步骤

  • 将头结点的指针域赋给尾结点(尾结点指向头结点下一结点)
  • 释放原头结点
  • 让头结点指向尾结点,重复以上步骤直至头结点为空

算法实现

void DestroyQueue(LinkQueue &Q) 
{
while (Q.front) {
Q.rear = Q.front->next; 
free(Q.front);
Q.front = Q.rear;
}
}
4.入队

算法步骤

  • 为入队元素分配结点空间,用指针p指向。
  • 将新结点数据域置为e。
  • 将新结点插入到队尾 。
  • 修改队尾指针为p。

算法实现

void EnQueue(LinkQueue &Q,QElemType e)
{
	QueuePtr P = new QNode;//创建新节点
	P->data = e;//把要插入的数据放进节点中
	P->next = NULL;//因为在队尾插入,所以始终队尾的next为NULL
	Q.rear->next = P;//把新节点放在当前队尾的后面
	Q.rear = P;//然后更新队尾指针,指向新节点
}
5.出队

算法步骤

  • 判断队列是否为空,若空则返回ERROR。
  • 临时保存队头元素的空间,以备释放。
  • 修改队头指针,指向下一个结点。
  • 判断出队元素是否为最后一个元素,若是,则将队尾指针重新赋值, 指向头结点。
  • 释放原队头元素的空间。

算法实现

void DeQueue(LinkQueue &Q,QElemType &e )
{ 
	if (Q.rear == Q.front)//判断队列是否为空
		return ERROR;
	QueuePtr p;
	p = Q.front->next;//使用p记录要被删除的节点
	e = p->data;//把删除的节点的数据给e
	Q.front->next = p->next;//头指针和p指向一致
	//如果队列的最后一个元素被删除了,要让尾指针重新指向头结点
	if (Q.rear == p) 
    {
		Q.rear = Q.front;//就要让尾指针重新等于头指针
	}
	delete p;//最后释放那个被删除的节点
}
6.取队头元素

算法步骤

  • 当队列非空时,此操作返回当前队头元素的值,头指针保持不变

算法实现

int GetHead{LinkQueue Q)
 {
if(Q.front!=Q.rear) //队列非空
return Q.front->next->data;
 }
7.判断队列是否为空

算法步骤

判断头指针尾指针是否都指向头结点

bool QueueEmpty(LinkQueue Q)
{
	if (Q.rear == Q.front)
		return true;
	return false;
}
8.求队列长度

算法步骤

  • 设置计数器,从首元结点开始累加
  • 计数器从1开始累加,直到等于尾结点

算法实现

int QueueLength(LinkQueue Q) 
{
	QueuePtr p;
	int i = 1;
	p = Q.front->next;
	while (p != Q.rear) {
		cout<<"data:"<<p->data;
		i++;
		p = p->next;
	}
	return i;
}



眉目作山河