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