1.链队的结构与初始化
链队结构如同单链表,但是带有两个指向头结点与尾节点的指针,用来插入与删除,不属于双向链表,第一次看觉得有些类似
结构体
// 1.链队的使用
// 节点定义
typedef struct LinkNode
{
int data;
struct LinkNode *next;
} LinkNode;
// 链队类型定义
typedef struct
{
LinkNode *front; //链队的第一个节点
LinkNode *rear; //链队的最后一个节点
} LiQueue;
初始化
// 2.链队初始化
void initQueue(LiQueue *qu)
{
qu->front = qu->rear = (LinkNode *)malloc(sizeof(LinkNode));
qu->front->next = NULL;
}
// 3.判空
int isQueueEmpty(LiQueue *qu)
{
return qu->front == qu->rear; //重合,即为空队
}
2.链队的基本操作(带头与不带头)
1.入队操作
//入队操作:带头结点
void EnQueue(LiQueue &qu, int x)
{
//创建插入的节点
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = x;
//队尾入队
s->next = NULL;
qu.rear->next = s;
qu.rear = s;
}
//入队:不带头结点
void EnQueue1(LiQueue &qu, int x)
{
LinkNode *s = (LinkNode *)malloc(sizeof(LinkNode));
s->data = x;
//若为首元素
if (qu.front == NULL)
{
qu.front = s;
qu.rear = s;
}
else
{
qu.rear->next = s;
qu.rear = s;
}
}
2.出队操作
总结:出队操作中,从一开始,队头元素就即qu->front都指向队头元素,
让qu->next指向下一个元素:qu->next指向队列的第一个元素
出队需不需要把节点所占空间删除,有待考究(40819真)
// 1.出队带头结点
bool DeQueue(LiQueue &qu, int &x)
{
if (qu.front == qu.rear)
return false; //空表
LinkNode *p = qu.front->next;
x = p->data;
qu.front->next = p->next;
//特殊情况:头结点+只剩一个节点,最后一个元素出队
if (qu.rear == p)
qu.rear = qu.front;
free(p);
return true;
}
// 2.出队不带头结点
bool DeQueue1(LiQueue &qu, int &x)
{
//队伍为空
if (qu.front == NULL)
return false;
//队伍非空
x = qu.front->data;
//创立一个新的指针,指向下一个未删除的位置
LinkNode *p = qu.front;
qu.front = p->next;
//这里有个判断条件:当队列中只有一个元素的时候
if (qu.rear == p)
{
qu.front = NULL;
qu.rear = NULL;
}
free(p);
return true;
}