循环链表
循环链表一个比较特殊的单链表,与单链表不同的地方是,最后一个节点的next指针指向第一个元素,形成一个环形,就是循环链表。还有一个特点,就是从任一节点出发均可找到表中的其他节点。见下图。
但是如果一个链表中只有一个元素该如何表示?不难,见下图。
看到了没有,就是这样,自己和自己玩。
好了,用代码描述一下。
1. 结构
循环链表的结构和单链表的结构一样。
typedef struct LoopList
{
int data;
struct LoopList* next;
} LoopList;
2. 代码示例
创建一个只有一个节点的链表。
void CreateLoopList_single()
{
pLLHead = (LoopList*)malloc(sizeof(LoopList));
pLLHead->data = rand() % 100;
pLLHead->next = pLLHead;
}
创建多个节点的循环链表
//初始化多个节点
void CreateLoopList(int num)
{
LoopList* pNew = NULL;
LoopList* pTail = NULL;
int i;
for (i = 0; i < num; i++)
{
pNew = (LoopList*)malloc(sizeof(LoopList));
pNew->data = rand() % 100;
//保存头指针
if (i == 0)
{
pLLHead = pNew;
pNew->next = pLLHead;
}
else
{
pTail->next = pNew;
pNew->next = pLLHead;
}
pTail = pNew;
}
}
打印循环链表
//打印链表
void PrintLoopList(LoopList* ll)
{
int i = 0;
if (!ll)
{
printf("链表为空");
return;
}
while (ll->next!= pLLHead)
{
printf("%d:\t%d\n", i++, ll->data);
ll = ll->next;
}
printf("%d:\t%d\n", i++, ll->data);
}
敲黑板:
while (ll->next!= pLLHead) 不能写成 while (ll->next!= ll),如果不懂,试试就知道了。
3. 测试代码
#include <stdio.h>
#include<time.h>
#define MAXSIZE 10
#include "looplist.h"
LoopList* pLLHead = NULL;
int main()
{
int i;
srand((unsigned int)time(NULL));
//CreateLoopList_single();
//printf("\t首地址:%x\n\t数 值:%x\n\tnext->: %x\n", pLLHead, pLLHead->data, pLLHead->next);
CreateLoopList(5);
PrintLoopList(pLLHead);
system("pause");
}
4. 小结
- 循环链表和单链表的区别是最后的节点的指针指向,单链表指向NULL,循环链表指向头节点。
- 循环链表遍历,ll->next!= pLLHead,要理解这行代码,意思是什么时候下一个指针指向头节点,则说明遍历到最后了。
- 如何确定头节点?你可以将第一个创建的节点作为头节点,也可以将任意一个节点设置头节点,视情况而定,一般将第一个创建的节点作为头节点。
- 其他删除、插入的代码没有写,可以参考前一章单链表,稍微改动就行。改哪里?请往上看。