单向循环链表
单向链表是最简单的线性链式存储结构。可以通过头结点遍历整个链表。
如上图所示,单向循环链表就是申请的一块块堆空间,通过指针将其串联起来,其中head指针存在栈空间,其内容存的是堆空间头结点的地址,所有操作都需要通过head指针来实现。
使用结构体来实现单向循环链表,结构体中有数据域和指针域两个部分,其中数据域用来存储数据,指针域是指向下一个数据的。
typedef struct sgl_crclist{
int data;
struct sgl_crclist *next;
}my_sgl_crclist, *p_sgl_crclist;
头节点设计
新建一个单向循环链表,将其指针返回作为指向头结点的指针head。
p_sgl_crclist init_crclist()
{
p_sgl_crclist head = new_node_crclist(); //新建一个节点作为头结点
head->next = head;
return head;
}
新建节点
调用calloc函数新建一个节点,该函数返回新建节点的地址,方便后续操作。
p_sgl_crclist new_node_crclist()
{
p_sgl_crclist new = calloc(1, sizeof(my_sgl_crclist));
if(NULL == new)
{
return NULL;
}
return new;
}
插入数据
头插法
bool add_crclist(p_sgl_crclist head)
{
int data;
p_sgl_crclist new_node = new_node_crclist(); //新建节点
p_sgl_crclist pos = head;
printf("Please enter the data you want to insert:");
scanf("%d", &data);
while('
' != getchar());
new_node->data = data;
new_node->next = head->next;
head->next = new_node;
}
尾插法
bool add_crclist_tail(p_sgl_crclist head)
{
int data;
p_sgl_crclist new_node = new_node_crclist();
p_sgl_crclist pos = head;
printf("Please enter the data you need to tail:");
scanf("%d", &data);
while('
' != getchar());
new_node->data = data;
while(pos->next != head)
pos = pos->next;
new_node->next = head;
pos->next = new_node;
}
打印链表数据
一个一个节点移动指针pos,并取出里面的数据将其打印出来。
void display_crclist(p_sgl_crclist head)
{
p_sgl_crclist pos = head->next;
for(int i = 0; pos != head; i++)
{
printf("The data of node %d is:%d
", i, pos->data);
pos = pos->next;
}
}
查找数据
查找链表中是否有某个数据,有的话返回该数据所在节点的地址。
p_sgl_crclist find_data(p_sgl_crclist head, int fdata)
{
p_sgl_crclist pos = head->next;
while(pos != head)
{
if(pos->data == fdata)
{
return pos;
}
else
{
pos = pos->next;
}
}
printf("No data to found
");
return NULL;
}
删除数据
删除节点中的指定数据,此函数将调用函数find_data,用来获取指定数据所在的节点地址。
bool del_node_data(p_sgl_crclist head)
{
int del_data;
p_sgl_crclist delnode;
p_sgl_crclist pos = head;
printf("Please enter the data you want to delete:
");
scanf("%d", &del_data);
while('
' != getchar());
delnode = find_data(head, del_data);
if(delnode == NULL)
return NULL;
while(pos->next != delnode)
{
pos = pos->next;
if(pos == NULL)
{
printf("node is error
");
return NULL;
}
}
pos->next = delnode->next;
delnode->next = NULL;
return true;
}
更改数据
将链表中的某个数据修改成指定数据,此函数将调用find_data,用来获取需要修改数据所在节点的地址。获取到地址后判断不为空时,直接修改即可。
bool mod_node_data(p_sgl_crclist head)
{
int old_data;
int new_data;
p_sgl_crclist modnode;
printf("Please enter the old and new data that need to be changed:");
scanf("%d %d", &old_data, &new_data);
while('
' != getchar());
modnode = find_data(head, old_data);
if(modnode == NULL)
return false;
modnode->data = new_data;
return true;
}
测试代码
int test()
{
p_sgl_crclist head = init_crclist();
add_crclist(head);
add_crclist(head);
add_crclist(head);
add_crclist(head);
add_crclist(head);
display_crclist(head);
mod_node_data(head);
display_crclist(head);
.....
.....
return 0;
}