注意不设头指针)试编写相应的置空队,判空对,入队,出队等算法。
步骤:1.通过InitQueue()函数来置空队
2.通过EmptyQueue()函数来判空队
3.通过EnQueue()来入队
4.通过DeQueue()来出队
算法分析
置空:已知队尾元素节点指针,所谓置空即为头结点指向队尾元素,但当该队列中含有其他元素时通过循环语句将所有元素释放掉,回收空间。
判空:由于该队列是由循环链表来进行表示的,所以当该队为空时,头结点的next就会指向自己。
入队:利用尾插法,再插入前要申请新的空间,将新节点由尾部连入,尾结点对应指针后移。
出队:由头部出队,p指向要出队的节点,x保存该节点中的数据,当该节点出队后该队列为空,则将队尾指针指向头结点,还有其他节点时,出队,并释放p。
程序流程图
1.置空队算法:
2.判空队算法:
3.入队算法:
4出队算法:
算法代码如下
/*name:雷桂艺
time:2021年12月8日20:30
version:1.0
description:置空:已知队尾元素节点指针,所谓置空即为头结点指向队尾元素,但当该队列中含有其他元素时通过循环语句将所有元素释放掉,回收空间。
判空:由于该队列是由循环链表来进行表示的,所以当该队为空时,头结点的next就会指向自己。
入队:利用尾插法,再插入前要申请新的空间,将新节点由尾部连入,尾结点对应指针后移。
出队:由头部出队,p指向要出队的节点,x保存该节点中的数据,当该节点出队后该队列为空,则将队尾指针指向头结点,还有其他节点时,出队,并释放p。
*/
//算法如下
//先定义链队结构
typedef struct queuenode{ //结点类型的定义
Datetype data;
struct queuenode *next;
} QueueNode;
typedef struct{ //只设一个指向队尾元素的指针
queuenode *rear;
}LinkQueue;
//置空队
void InitQueue(LinkQueue *Q)
{ //置空队:就是使头结点成为队尾元素
QueueNode *s;
Q->rear = Q->rear->next; //将队尾指针指向头结点
while (Q->rear != Q->rear->next) //当队列非空,将队中元素逐个出队
{
s = Q->raer->next;
Q->rear->next = s->next;
free(s);
} //回收结点空间
}
//判队空
int EmptyQueue(LinkQueue *Q)
{/判队空,当头结点的next指针指向自己时为空队
return Q->rear->next == Q->rear; /
}
//入队
void EnQueue(LinkQueue *Q, Datatype x) //入队,也就是在尾节点处插入元素
{
QueueNode *p = (QueueNode *)malloc(sizeof(QueueNode)); //申请新结点
p->data = x; p->next = Q->rear->next; //初始化新结点并链入
Q - rear->next = p;
Q->rear = p; //将尾指针移至新结点
}
// 出队
Datatype DeQueue(LinkQueue *Q) //出队,把头结点之后的元素摘下
{
Datatype x;
QueueNode *P;
if (EmptyQueue(Q))
Error("Queue underflow");
p = Q->rear->next->next; //p指向将要摘下得结点
x = p->data; //保存结点中的数据
if (p == Q->rear) //当队列中只有一个结点时,p结点出队后,要将队尾指针指向头结点
{
Q->rear = Q->rear->next; Q->rear->next = p->next;
}
else
Q->rear->next = p->next;
free(p); //摘下结点p
return x; //释放被删结点