C语言单链表(初始化,添加元素,插入元素,删除指定元素,列表反转,清空列表)
这两天复习基础,关于C语言单链表的操作,自己理解整理了一下,博客记录一下。
本文操作的是有首节点的单链表,首节点作用:使链表的其他节点的插入删除操作可以统一,不用考虑链表头指针情况。
头文件:single_list_practice.h
#ifndef single_list_practice_h
#define single_list_practice_h
#include <stdio.h>
#include <stdbool.h>
typedef struct my_list{
int v;
struct my_list *next;
}MY_LIST;
void InitList(MY_LIST **pHead);
void AddItem(MY_LIST *pHead, int a);
MY_LIST *FindElem(MY_LIST *pHhead, int a, bool pos);
void InsertItem(MY_LIST *pItem, int a);
void PrintList(MY_LIST *pHead);
void DelItem(MY_LIST *pHead, int item);
void CleanMyList(MY_LIST *pHead);
void ReverseMyList(MY_LIST *pHead);
#endif /* single_list_practice_h */
源文件:single_list_practice.c
#include "single_list_practice.h"
#include <stdlib.h>
#include <stdbool.h>
//创建链表头结点,头结点内容不在意,创建头结点的意义在于,将链表的首元节点的插入删除啥的,跟其余节点保持一致 不用单独处理
void InitList(MY_LIST **pHead){
*pHead = (MY_LIST *)malloc(sizeof(MY_LIST));
if (NULL == *pHead){
printf("pHead failed!\n");
return;
}
(*pHead)->next = NULL;
return;
}
//像链表末尾添加元素
void AddItem(MY_LIST *pHead, int a){
MY_LIST *node = (MY_LIST *)malloc(sizeof(MY_LIST));
node->v = a;
node->next = NULL;
MY_LIST *end = pHead; //找到链表的尾节点,将新建的节点插入其后面即可。
while(end){
if (end->next == NULL){
break;
}
end = end->next;
}
end->next = node;
printf("-------Add item is %d---------\n", node->v);
return;
}
//遍历打印列表元素,测试用
void PrintList(MY_LIST *pHead){
if (pHead->next == NULL){
printf("List is NULL.\n");
return;
}
MY_LIST *temp = pHead->next;
while (temp) {
printf("-------Current item is %d---------\n", temp->v);
temp = temp->next;
}
}
//查找给定元素的节点信息,此处考虑到有的时候需要查找给定元素前面一个节点信息,因此设置了bool标志位
MY_LIST *FindElem(MY_LIST *pHhead, int a, bool pos)
{
MY_LIST *temp = pHhead;
MY_LIST *prev = NULL;
while(temp){
if (temp->v == a){
break;
}
prev = temp;
temp = temp->next;
}
//我们约定pos等于0 返回item所在的节点,pos=1返回item之前的节点
return (!pos) ? prev : temp;
}
//在指定元素位置之后插入新的元素
void InsertItem(MY_LIST *pItem, int a){
if (NULL == pItem){
printf("Node is not exist!\n");
}
MY_LIST *newNode = (MY_LIST *)malloc(sizeof(MY_LIST));
newNode->v = a;
newNode->next = NULL;
MY_LIST *temp = pItem->next;
pItem->next = newNode;
newNode->next = temp;
}
//删除给定元素节点信息
void DelItem(MY_LIST *pHead, int item){
MY_LIST *itemPrev = FindElem(pHead, item, 0);
if (NULL == itemPrev){
printf("Something error!\n");
}
MY_LIST *pItem = itemPrev->next;
itemPrev->next = pItem->next;
free(pItem);
pItem = NULL;
}
//销毁除了头结点之外的列表节点,思想是依次销毁头结点后面的节点,类似节点删除,直到头结点的指针指向NULL为止
void CleanMyList(MY_LIST *pHead){
MY_LIST *temp = pHead->next;
MY_LIST *pNext = NULL;
while(temp){
pNext = temp->next;
pHead->next = pNext;
free(temp);
temp = pNext;
}
if (pHead->next == NULL){
printf("Clear my list successs!\n");
}
return;
}
//链表反转
void ReverseMyList(MY_LIST *pHead){
MY_LIST *cur = pHead->next;
MY_LIST *curNext = NULL;
MY_LIST *temp = NULL;
while(cur){
curNext = cur->next;
cur->next = temp;
temp = cur;
cur = curNext;
}
pHead->next = temp;
}
测试结果如下截图: