1.队列的单向链表的实现方法
return只可以返回一个值,单向循环链表来实现队列的时候可以只保留一个指针,因为保留rear指针能够很方便的表示出front指针,所以保留rear指针。
另外由于链表的第一个结点处理比较特殊,所以在初始化的时候需要单独处理。链表实现的队列思想也是第一个单元作为头结点,不存放数据,rear指针指向的总是尾结点(在循环链表中也就是头结点的上一个结点)。
2.实现方法
程序运行截图:
return只可以返回一个值,单向循环链表来实现队列的时候可以只保留一个指针,因为保留rear指针能够很方便的表示出front指针,所以保留rear指针。
另外由于链表的第一个结点处理比较特殊,所以在初始化的时候需要单独处理。链表实现的队列思想也是第一个单元作为头结点,不存放数据,rear指针指向的总是尾结点(在循环链表中也就是头结点的上一个结点)。
2.实现方法
用带表头的单向循环链表来实现
#include <stdio.h>
#include <malloc.h>
#define NULL 0
typedef struct sq
{
int data;
struct sq *next;
}ElemSN;
ElemSN * in_quence(ElemSN *rear, int val) /*入队函数*/
{
ElemSN *p;
p = (ElemSN *)malloc(sizeof(ElemSN));
p->data = val;
p->next = rear->next;
rear->next = p;
rear = rear->next;
return rear;
}
int out_quence(ElemSN *rear)
{
ElemSN *p = rear->next; /*rear的下一个结点是头结点*/
int dat;
p = p->next; /*p此时才指向第一个有数据的结点(表头结点的下一个结点)*/
dat = p->data;
rear->next->next = p->next; /*等价于head->next = p->next,因为rear的下一个结点是头结点*/
free(p);
return dat;
}
void print_quence(ElemSN *rear)
{
ElemSN *p = rear->next;
p = p->next; /*指向第一个有数据的单元*/
do
{
printf("%d ", p->data);
p = p->next;
}while(p != rear->next);
}
ElemSN * clear_quence(ElemSN *rear)
{
ElemSN *p, *q;
p = rear->next;
while(p != p->next)
{
q = p->next;
p->next = q->next;
free(q);
}
return p;
}
int main()
{
ElemSN *rear, *s;
int dat[6] = {1, 2, 3, 4, 5, 6};
int i;
rear = (ElemSN *)malloc(sizeof(ElemSN)); /*表头的创建*/
rear->data = NULL;
rear->next = rear;
for(i = 0; i < 6; i++)
{
rear = in_quence(rear, dat[i]);
print_quence(rear);
printf("\n");
}
printf("%d is out quence.\n", out_quence(rear)); /*出队一个元素*/
print_quence(rear);
printf("\n");
rear = clear_quence(rear);
return 0;
}
程序运行截图:
注意:使用不带表头的循环链表也是可以实现的,但是对于队列为空时rear指针的值为多少,第一个结点如何插入,以及队列中只有一个元素的时候出队的操作都是需要特殊处理的。这里就不再具体实现了,因为带表头的链表相对于不带表头的链表操作上有相当多的方便之处。