// 循环链表
// 循环链表的最大的特点是尾结点的指针域指向第一个结点
// 优点是能够通过任意结点遍历整个链表结构
#include<stdio.h>
#include<iostream>
using namespace std;
// 1、定义数据元素
struct ElementType
{
int id;
char* name;
};
ElementType dataArray[] = { { 1, "史莱克" },
{ 2, "哥斯拉" },
{ 3, "蜥蜴长者" },
{ 4, "远古魔像" },
{ 5, "纳什男爵" }
};
// 2、定义循环链表结点
struct CircularNode
{
ElementType data; // 数据域
CircularNode* next; // 指向下个结点的指针域
};
// 3、定义链表结构
struct CircularLinkList
{
CircularNode* next; // 指向第一个结点的指针,头指针
int length; // 循环链表的长度
};
// 4、在循环链表的指定位置插入元素,定义插入函数
// 第一种情况:链表的长度为0
// 第二种情况:链表的长度不为0
void InsertCircularLinkList(CircularLinkList* cList, int pos, ElementType element);
// 5、打印循环链表
void PrintCircularLinkList(CircularLinkList* cList);
// 6、 初始化循环列表
void InitCircularLinkList(CircularLinkList* cList, ElementType* dataArray, int length);
// 7、删除并返回循环链表中指定位置的元素
ElementType DeleteCircularLinkList(CircularLinkList* cList, int pos);
// 8、根据元素内容返回对应的结点指针
CircularNode* GetCircularLinkListNode(CircularLinkList* cList, ElementType element);
// 9、通过给定的某个结点,循环遍历出链表中的每个元素
void PrintCircularLinkListByNode(CircularLinkList* cList, CircularNode* node);
void Test()
{
CircularLinkList* cList = new CircularLinkList();
cList->length = 0;
cList->next = NULL;
InsertCircularLinkList(cList, 1, dataArray[0]);
PrintCircularLinkList(cList);
// 测试初始化
cout << "===========测试初始化===============" << endl;
InitCircularLinkList(cList, dataArray, 4);
PrintCircularLinkList(cList);
// 测试删除结点
cout << " ===========测试删除结点===========" << endl;
ElementType deleElem = DeleteCircularLinkList(cList, 2);
PrintCircularLinkList(cList);
// 测试根据某个结点,循环遍历链表中的每个元素
cout << "===========根据某个结点遍历============" << endl;
ElementType elem;
elem.id = 3;
elem.name = "蜥蜴长者";
CircularNode* node = GetCircularLinkListNode(cList,elem);
PrintCircularLinkListByNode(cList, node);
}
int main()
{
Test();
system("pause");
}
void InsertCircularLinkList(CircularLinkList* cList, int pos, ElementType element)
{
// 创建一个空结点
CircularNode* node = new CircularNode();
node->data = element;
node->next = NULL;
if (pos == 1)
{
node->next = cList->next;
if (!node->next) // 如果插入的链表长度为0
node->next = node;
else
{
// 如果长度不为0,就要找到链表的最后一个结点并改变其指针域
CircularNode* lastNode = cList->next;
for (int i = 0; i < cList->length; i++)
{
lastNode = lastNode->next;
}
lastNode->next = node;
}
cList->next = node;
cList->length++;
return;
}
else
{
// 插入的不是第一个结点
CircularNode* currNode = cList->next;
for (int i = 0; currNode && i < pos - 1; i++)
{
currNode = currNode->next;
}
if (currNode)
{
node->next = currNode->next;
currNode->next = node;
cList->length++;
if (pos == cList->length)
{
node->next = cList->next;
}
}
}
}
void PrintCircularLinkList(CircularLinkList* cList)
{
if (cList->length == 0 || !cList->next)
{
cout << "链表长度为空,没有内容可以打印!" << endl;
cList->length = 0;
return;
}
CircularNode* node = cList->next;
for (int i = 0; i < cList->length; i++)
{
cout << "id:" << node->data.id << " " << "name:" << node->data.name << endl;
node = node->next;
}
}
void InitCircularLinkList(CircularLinkList* cList, ElementType* dataArray, int length)
{
for (int i = 0; i < length; i++)
{
InsertCircularLinkList(cList, i + 1, dataArray[i]);
}
}
ElementType DeleteCircularLinkList(CircularLinkList* cList, int pos)
{
ElementType element;
element.id = -999;
if (pos == 1)
{
CircularNode *node = cList->next;
if (node)
{
element = node->data;
// 第一个结点不为空,改变其指针域的指向
CircularNode *lastNode = cList->next;
for (int i = 1; i < cList->length; i++)
{
lastNode = lastNode->next;
}
cList->next = node->next;
lastNode->next = cList->next;
delete(node);
cList->length--;
}
return element;
}
CircularNode* preNode = NULL;
CircularNode* node = cList->next;
for (int i = 1; node && i < pos; i++)
{
preNode = node;
node = node->next;
}
if (node)
{
element = node->data;
preNode->next = node->next;
delete(node);
cList->length--;
}
return element;
}
CircularNode* GetCircularLinkListNode(CircularLinkList* cList, ElementType element)
{
CircularNode* node = cList->next;
if (!node) return NULL;
// 不使用循环变量i来遍历循环链表的方法
do
{
if (element.id == node->data.id && strcmp(element.name, node->data.name) == 0)
return node;
node = node->next;
} while (node != cList->next);
return NULL;
}
void PrintCircularLinkListByNode(CircularLinkList* cList, CircularNode* node)
{
if (!node || !cList->next)
{
cout << "链表长度为空,没有内容可以打印!" << endl;
return;
}
// 记录下初始的结点指针
CircularNode *origNode = node;
do
{
cout << node->data.id << " " << node->data.name << endl;
node = node->next;
} while (node != origNode);
}