單向循環鏈表
單向鏈表是最簡單的線性鏈式存儲結構。可以通過頭結點遍歷整個鏈表。
如上圖所示,單向循環鏈表就是申請的一塊塊堆空間,通過指針將其串聯起來,其中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('\n' != 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('\n' != 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\n", 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\n");
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:\n");
scanf("%d", &del_data);
while('\n' != 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\n");
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('\n' != 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;
}