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;

}

 

测试结果如下截图:

C语言单链表(初始化,添加元素,插入元素,删除指定元素,列表反转,清空列表)