循环链表的创建以及基本操作
上篇我们讲了运用头插法和尾插法创建单链表的方法,和两种方法的比较。 接着我们学习循环链表的创建。
只要学会了单链表的创建,循环链表的创建就变得很简单。
循环链表创建
单链表的结构:
循环链表:
所谓循环链表,就是将单链表的尾结点 end 的指针域 也就是 end->next 指向头结点的地址 : end->next = head 。 这样就完成了循环链表的创建。
这就完了? 当然没有那么简单了~~~
循环链表不同于单链表,原因在于上篇我们讲单链表的时候,尾结点指针域的指向永远是 NULL,也就是 end->next = NULL。 因此判断单链表结束的标志,就是 while( node->next != NULL) ,但是循环链表的尾结点指向的不是 NULL ,而是 头结点 head。因此,我们判断的标准也要改变。
思考过后,决定将头结点的数据域赋值为 -1,这样就有了一个标志,用来判断是否将循环链表执行完一次。
思而不学则殆,即刻上手!
Linklist Creat_list(Linklist head) {
LNode *node = NULL;
LNode *end = NULL;
head = (Linklist)malloc(sizeof(LNode));
head->next = NULL;
head->data = -1;
end = head;
int count = 0;
printf("Input node numbers: ");
scanf("%d", &count);
for (int i = 0; i < count; i++) {
node = (LNode*)malloc(sizeof(LNode));
node->data = i;
end->next = node;
end = node;
}
end->next = head; // 将尾结点的指针指向头结点
return head;
}
这就完成了循环链表的创建,接下来我们要想办法让循环链表按照我们预想来执行循环的次数。
思前想后,想出了这个函数来判断一个循环链表内的结点数。
int node_number(Linklist *head) {
Linklist tem = head;
tem = tem->next; // 因为头结点的数据域值为-1,因此需要从头结点的下一个结点开始
int count = 0; // 计数结点的个数
while (tem->data != -1){ // 因为将头结点的数据域赋值-1,因此-1相当于一个标签
count++; // 没执行一次,结点数就多一个
tem = tem->next; // 下一个结点
}
return count + 1; // 因为第一次执行循环之前,跳过了头结点,因此得到的count 没有算头结点,返回的时候我们加上1
}
这样我们便得到了循环链表的结点个数。
只要有了结点个数,我们就可以根据我们的需求来执行输出循环链表所有结点的次数。
void Illustrate(Linklist head) {
Linklist tem = head;
int size = node_number(head)*2; // *2 表示将循环链表执行两次
for (int i = 0; i < size; i++) { // size 表示需要通过的结点的个数。
printf("%d ", tem->data);
tem = tem->next;
}
}
这样我们就完成了循环链表的创建以及控制输出。