循环链表是通过单链表改变而来的,两者的区别就是循环链表的最后一个元素的指针重新指向头指针或第一个节点。所以两者的思路基本是相似的而且循环链表的功能可能更完全,今天对循环链表进行一个小的总结。
首先,我们的循环链表有和单链表一样的结构体
typedef struct Node
{
int data;
struct Node* Next;
}Node;
其结构体中依然只有两个元素分别是存储的数据和下一个数据的地址。
在此我们将说明循环链表的3个基本的操作。链表的初始化,对链表进行元素的插入,对链表进行元素的删除。
1.链表的初始化
大概思路先看该链表是不是一个空链表,如果是空链表我们会为其开创相应的空间并对其进行赋值,如果不是一个空链表我们会先找该链表的最后的一个元素找到后将最后一个元素插入并且将其相应的指向地址改为第一个节点的地址。
相应的实现代码如下
//对循环链表的初始化
void init(Node** pnode)
{
int item;
Node* temp;
Node* traget;
printf("输入节点的值,输入0完成初始化");
while (1)
{
scanf("%d", &item);
if (item == 0)
{
return;
}
//看链表是不是一个空链表
if (*pnode == NULL)
{
*pnode = (Node*)malloc(sizeof(struct Node));//开辟一个相应空间
if (*pnode == NULL)
{
exit(0);
}
(*pnode) -> data = item;
(*pnode)->Next = *pnode;
}
else
{
for (traget == *pnode; traget->Next != *pnode; traget = traget->Next);//寻找最后一个节点
temp= (Node*)malloc(sizeof(struct Node));//开辟一个相应空间
if (temp == NULL)
{
exit(0);
}
temp->data = item;
temp->Next = *pnode;
traget->Next = temp;
}
}
}
在这段代码中我们用了一个 while循环但是跳出条件是1所以在这个循环中我们只能通过return来进行跳出。当链表为空表的时候,我们将item给了temp然后将链表进行了创建。如果不是空链表我们先用循环找到最后一个元素然后将想加入的值加在其后面,然后在将其指针指向第一个元素。自此循环链表的创建完成。
2.对链表进行元素的插入
对与插入来说我们也有大概的思路。我们首先要确定插入的位置,是插入开头还是其他位置。我们要这样考虑的原因是因为如果插入开头我们要改变最后一个元素的地址指向而其他的则不需要考虑这么多。
一下将是代码的说明
//向链表中插入节点
void insert(Node** pnode, int i)
{
Node* temp;
Node* traget;
Node* p;
int item;
int j = 1;
printf("输入想要插入的值");
scanf("%d", &item);
//如果想要在第一个位置上进行插入
if (i == 1)
{
temp = (Node*)malloc(sizeof(struct Node));//开辟一个相应空间
if (temp == NULL)
{
exit(0);
}
temp->data = item;
temp->Next = (*pnode);
for (traget == *pnode; traget->Next != *pnode; traget = traget->Next);//寻找最后一个节点
traget->Next = temp;
(*pnode) = temp;//对第一个节点进行更新
}
else
{
traget = (*pnode);
for (j; j < i - 1; j++)
{
traget = traget->Next;
}
temp = (Node*)malloc(sizeof(struct Node));//开辟一个相应空间
if (temp == NULL)
{
exit(0);
}
temp->data = item;
temp->Next = traget->Next;
traget->Next = temp;
}
}
在这段代码中我们的实现基本和我们的思路讲解完全一样,值得注意的是在else中我们的倒数第二行应该是将traget的一个next就可以完成我们的目的。
3.对链表进行元素的删除
对应删除的思路更加的简单我们只需要将想要删除的元素位置找到就可以了。
代码的实现如下
//向链表中的元素进行删除
void delete(Node** pnode, int i)
{
Node* temp;
Node* traget;
int j = 1;
//如果删除的是第一个节点
if (i == 1)
{
for (traget == *pnode; traget->Next != *pnode; traget = traget->Next);//寻找最后一个节点
temp = (*pnode);
traget->Next = (*pnode)->Next;
(*pnode) = (*pnode)->Next;
free(temp);
}
else
{
traget = (*pnode);
for (j; j < i - 1; j++)
{
traget = traget->Next;
}
temp = traget->Next;
traget->Next = temp->Next;
free(temp);
}
}
注意我们一定要保证temp先对要删除元素进行保留要不然在改变之后我们无法对删除的元素进行释放,会导致内存的浪费。
到这里我们对循环链表的总结就结束了,如果大家检查出文章的问题请多指教