c语言 增删查 案例,C语言实现单链表的增删查改
#include
#include
#include"linklist.h"
#define Test_Header printf("\n-----%s-----\n",__FUNCTION__);
//初始化函數
void linklistInit(LinkNode **head)
{
*head = NULL;
}
//創建新節點函數
LinkNode *CreateNode(LType value)
{
//為新節點申請空間
LinkNode *new_node = (LinkNode*)malloc(sizeof(LinkNode));
//給新節點賦值
new_node->data = value;
//將新節點的next指向空
new_node->next = NULL;
return new_node;
}
//銷毀一個節點
void DestroyNode(LinkNode *node)
{
free(node);
}
//順序打印鏈表元素
void linklistPrint(LinkNode *head)
{
if(head == NULL)
{
//空鏈表無需打印
return;
}
LinkNode *cur = head;
//遍歷鏈表
while(cur != NULL)
{
//打印元素和其對應的地址
printf("%c|%p\n",cur->data,cur);
//移動cur,以達到遍歷鏈表的目的
cur = cur->next;
}
printf("\n\n");
}
//逆序打印鏈表(遞歸思想)
void linklistReversePrint(LinkNode *head)
{
if(head == NULL)
{
//空鏈表無需打印,也是遞歸的出口
return;
}
linklistReversePrint(head->next);
printf("%c|%p ",head->data,head);
printf("\n");
}
//尾插函數
LinkNode *linklistPushBack(LinkNode **head,LType value)
{
//非法輸入
if(head == NULL)
{
return NULL;
}
//空鏈表
if(*head == NULL)
{
//直接創建一個新的節點完成元素插入
*head = CreateNode(value);
return NULL;
}
else
{
LinkNode *cur = *head;
//遍歷鏈表,讓cur指向最后一個元素
while(cur->next != NULL)
{
cur = cur->next;
}
//創建一個新節點
LinkNode *new_node = CreateNode(value);
//將最后一個元素的next指向新節點
cur->next = new_node;
return new_node;
}
}
//尾刪函數
void linklistPopBack(LinkNode **head)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表沒有可刪除的元素
if(*head == NULL)
{
return;
}
//只有一個元素
if((*head)->next == NULL)
{
//直接刪除節點
DestroyNode(*head);
//將頭結點置空
*head = NULL;
return;
}
else
{
LinkNode *cur = *head;
//遍歷鏈表,使cur指向倒數第二個元素
while(cur->next->next != NULL)
{
cur = cur->next;
}
//創建指針指向最后一個元素,即我們需要刪除的元素
LinkNode *to_delete = cur->next;
//將該節點銷毀
DestroyNode(to_delete);
//將倒數第二個元素的next指向空
cur->next = NULL;
}
return;
}
//頭插函數
void linklistPushFront(LinkNode **head,LType value)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表
if(*head == NULL)
{
//直接創建一個新節點完成插入
*head = CreateNode(value);
return;
}
else
{
//創建一個新的指針指向頭結點
LinkNode *new_node = *head;
//創建一個新的頭結點
*head = CreateNode(value);
//將新的頭結點的next指向舊的頭結點
(*head)->next = new_node;
}
return;
}
//頭刪函數
void linklistPopFront(LinkNode **head)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表沒有可刪除的元素
if(*head == NULL)
{
return;
}
else
{
//創建一個新的指針指向第二個元素
LinkNode *new_node = (*head)->next;
//將頭結點的next指向空
(*head)->next = NULL;
//刪除該頭結點
DestroyNode(*head);
//將第二個元素設置成新的頭結點
*head = new_node;
}
return;
}
//查找鏈表中指定元素的地址
LinkNode *linklistFind(LinkNode *head,LType to_find)
{
int count = 0;
LinkNode *find = head;
//空鏈表
if(head == NULL)
{
return;
}
else
{
//循環遍歷鏈表
for(;find->next != NULL;find = find->next)
{
if(find->data == to_find)
{
count++;
//找到了返回該元素的地址
return find;
}
}
}
//如果count計數為0,說明沒有鏈表中不存在想要查找的元素
if(count == 0)
{
printf("this value is non-existence\n");
}
//沒找到返回空
return NULL;
}
//在指定位置之前插入指定元素(遍歷)函數
//時間復雜度為O(n)
void linklistInsertBefore(LinkNode **head,LinkNode *pos,LType value)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表
if(*head == NULL)
{
//直接創建一個新的節點
*head = CreateNode(value);
return;
}
//如果是頭結點位置
if(pos == *head)
{
//則進行頭插
linklistPushFront(head,value);
return;
}
//如果為空
if(pos == NULL)
{
//則進行尾插
linklistPushBack(head,value);
return;
}
else
{
LinkNode *cur = *head;
//遍歷鏈表
while(cur->next != NULL)
{
//cur的下一個位置就是pos
if(cur->next == pos)
{
//創建一個指針,以value值創建節點
LinkNode *pre = CreateNode(value);
//將cur的next修改指向新的節點的位置
cur->next = pre;
//將新節點的next指向pos,就在pos位置之前插入了新元素
pre->next = pos;
return;
}
//將cur移向下一個元素,以達到遍歷鏈表的目的
cur = cur->next;
}
}
}
//在指定位置之前插入指定元素(不遍歷)函數
//時間復雜度為O(1)
void linklistInsertBefore1(LinkNode **head,LinkNode *pos,LType value)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表
if(*head == NULL)
{
//直接創建一個新的節點
*head = CreateNode(value);
return;
}
//如果是頭結點位置
if(pos == *head)
{
//則進行頭插
linklistPushFront(head,value);
return;
}
//如果位置為空
if(pos == NULL)
{
//則進行尾插
linklistPushBack(head,value);
return;
}
else
{
//定義一個新指針指向pos的下一個位置
LinkNode *cur = pos->next;
//用pos位置的值創建一個新的節點
LinkNode *new_node = CreateNode(pos->data);
//將pos位置的值修改為value
pos->data = value;
//將pos的next指向新的節點
pos->next = new_node;
//將新節點的next指向pos的next,即指向cur
new_node->next = cur;
}
}
//在指定位置之后插入指定元素
void linklistInsertAfter(LinkNode **head,LinkNode *pos,LType value)
{
//非法輸入
if(head ==NULL)
{
return;
}
//空鏈表
if((*head) == NULL)
{
//直接以value值創建一個頭結點
*head = CreateNode(value);
return;
}
//如果pos位置為空
if(pos == NULL)
{
//則進行尾插
linklistPushBack(head,value);
return;
}
//如果pos為頭結點的位置
if(pos == *head)
{
//則進行頭插
linklistPushFront(head,value);
return;
}
else
{
//創建一個新的指針指向頭結點
LinkNode *cur = *head;
//遍歷鏈表
while(cur->next != NULL)
{
//cur的下一個位置就是pos
if(cur->next == pos)
{
//以value值創建一個新的節點
LinkNode *new_node = CreateNode(value);
//新節點的next指向pos位置的next
new_node->next = pos->next;
//pos的next修改指向新的節點
pos->next = new_node;
}
//移動cur
cur = cur->next;
}
}
}
//刪除指定位置的元素(遍歷)函數
//時間復雜度為O(n)
void linklistErase(LinkNode **head,LinkNode *pos)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表
if(*head == NULL)
{
return;
}
//如果pos位置為空
if(pos == NULL)
{
//則進行尾刪
linklistPopBack(head);
return;
}
//如果pos為頭結點的位置
if(pos == *head)
{
//則進行頭刪
linklistPopFront(head);
return;
}
else
{
//創建新的指針指向頭結點
LinkNode *cur = *head;
//遍歷鏈表,遍歷完成以后cur的下一個位置就是pos
while(cur->next != pos)
{
cur = cur->next;
}
//將cur的next指向pos的next
cur->next = pos->next;
//銷毀pos節點
DestroyNode(pos);
}
}
刪除指定位置的元素(遍歷)函數
//時間復雜度為O(1)
void linklistErase2(LinkNode **head,LinkNode *pos)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表無法刪除
if(*head == NULL)
{
return;
}
//如果pos位置為空
if(pos == NULL)
{
//則進行尾刪
linklistPopBack(head);
return;
}
//如果pos為頭結點位置
if(pos == *head)
{
//則進行頭刪
linklistPopFront(head);
return;
}
else
{
//創建一個新的指針指向pos的next
LinkNode *to_delete = pos->next;
//將pos的下一個位置的元素賦給pos
pos->data = to_delete->data;
//再將pos的next指向其下一個元素的next
pos->next = to_delete->next;
//將pos的下一個位置節點刪除
DestroyNode(to_delete);
}
}
//刪除指定元素,若存在多個元素則只刪除第一個函數
void linklistRemove(LinkNode **head,LType to_delete)
{
//非法輸入
if(head == NULL)
{
return;
}
//空鏈表沒有可刪除的元素
if(*head == NULL)
{
return;
}
//如果頭結點的元素是要刪除的元素
if((*head)->data == to_delete)
{
//則進行頭刪
linklistPopFront(head);
return;
}
LinkNode *cur = *head;
//遍歷鏈表
while(cur != NULL && cur->next != NULL)
{
//要刪除的元素是cur的下一個元素
if(cur->next->data == to_delete)
{
//定義一個新的指針指向cur的下一個元素(待刪除元素)的位置
LinkNode *to_remove = cur->next;
//將cur的next指向其下一個元素(待刪除元素)的下一個位置
cur->next = to_remove->next;
//刪除新的節點(即一開始定義的指向待刪除元素的指針)
DestroyNode(to_remove);
return;
}
cur = cur->next;
}
}
//判斷鏈表是否為空鏈表
int linklistEmpty(LinkNode *head)
{
//為空返回0否則返回1
return head == NULL?0:1;
}
//求鏈表中元素個數,返回元素個數
size_t linklistSize(LinkNode *head)
{
//空鏈表返回0
if(head == NULL)
{
return 0;
}
size_t count = 0;
LinkNode *cur = head;
//遍歷鏈表
for(;cur != NULL;cur = cur->next)
{
count++;
}
return count;
}
//尾插的測試函數
void TestPushBack()
{
Test_Header;
//初始化鏈表
linklistInit(&head);
//尾插a b c d
linklistPushBack(&head,'a');
linklistPushBack(&head,'b');
linklistPushBack(&head,'c');
linklistPushBack(&head,'d');
linklistPrint(head);
}
//尾刪的測試函數
void TestPopBack()
{
Test_Header;
//尾刪3次
linklistPopBack(&head);
linklistPopBack(&head);
linklistPopBack(&head);
linklistPrint(head);
}
//頭插的測試函數
void TestPushFront()
{
Test_Header;
//頭插b c d
linklistPushFront(&head,'b');
linklistPushFront(&head,'c');
linklistPushFront(&head,'d');
linklistPrint(head);
}
//頭刪的測試函數
void TestPopFront()
{
Test_Header;
//頭刪3次
linklistPopFront(&head);
linklistPopFront(&head);
linklistPopFront(&head);
linklistPrint(head);
}
總結
以上是生活随笔為你收集整理的c语言 增删查 案例,C语言实现单链表的增删查改的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用对象操作流程,读写文件
- 下一篇: 国家级一级计算机考试题,国家级计算机一级