数据结构-单向链表

数据结构-链表


头文件:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

主函数:

//主函数
int main(int argc, const char *argv[])
{
    LkList_t *LkList = LkListCreate();              //初始化 
    printf("%#x\n",LkList);                         //打印地址

    LkListHeadInsert(LkList,10);                    //头节点后添加节点
    LkListHeadInsert(LkList,20);                    //头节点后添加节点
    LkListDestInsert(LkList,20,15);                 //指定节点后添加节点

    LkListTailInsert(LkList,9);                     //尾节点后添加节点
    LkListTailInsert(LkList,8);                     //尾节点后添加节点
    LkListTailInsert(LkList,7);                     //尾节点后添加节点

    LkListPrint(LkList);                            //20,15,10,9,8,7                               
    
    LkListHeadDel(LkList);                          //头节点后删除节点
    LkListTailDel(LkList);                          //删除尾节点
    LkListDestDel(LkList,10);                       //删除指定节点

   
    printf("\n");                                   
    LkListPrint(LkList);                            //15,9,8
    
}

函数功能实现

定义结构体

typedef int DataType_t;           //用户自定义指针类型

//定义结构体
typedef struct LinkedList   
{
    
    DataType_t Data;              //数据域 
    struct LinkedList *Next;      //指针域 

}LkList_t;                        //别名  

初始化

//创建头节点
LkList_t *LkListCreate(void)
{
   LkList_t *Head = (LkList_t *)calloc(1,sizeof(LkList_t));
    //判断申请堆内存是否成功   
    if (NULL == Head)
    {
        perror("Calloc memory for Head failed");
        exit(-1);
    }

   Head->Next=NULL;

   return Head;
}

创建独立节点

//创建独立节点
LkList_t *LkListNewNode(DataType_t Data)
{
    LkList_t *New = (LkList_t *)calloc(1,sizeof(LkList_t));
    //判断申请堆内存是否成功
    if (NULL == New)
    {
        perror("Calloc memory for New is failed");
        return NULL;
    }

    New->Data = Data;
    New->Next = NULL;
    
    return New;
     
}

插入节点

1.头节点后插入节点

2.尾节点后插入节点

3.指定节点后插入节点

//头节点后插入节点
bool LkListHeadInsert(LkList_t *Head , DataType_t Data)
{
    LkList_t *New = LkListNewNode(Data);    //调用函数创建新节点

    //判断是否创建成功
        if (NULL == New)
        {
            return false;
        }

    //如果为空链表,将头节点的Next指向新创建的节点    
    if (NULL == Head->Next)
    {
        Head->Next = New;
        return true;
    }
    else
    {
        New->Next = Head->Next;
        Head->Next = New;
    }
}



//尾节点后插入节点
bool LkListTailInsert(LkList_t *Head , DataType_t Data)
{

    LkList_t *New = LkListNewNode(Data);    //调用函数创建新节点

    //判断是否创建成功
        if (NULL == New)
        {
            return false;
        }

    //如果为空链表,将头节点的Next指向新创建的节点
    if (NULL == Head->Next)
    {
        Head->Next = New;
        return true;
    }
    //非空链表
    else
    {
        LkList_t *p = Head;             //将头节点地址赋值给p指针
        while (p->Next != NULL)
        {
            p = p->Next;
        }
        p->Next = New;   
    }
}



//指定位置插入节点
bool LkListDestInsert(LkList_t *Head , DataType_t Dest , DataType_t Data)
{

    LkList_t *New = LkListNewNode(Data);    //调用函数创建新节点

    //判断是否创建成功
        if (NULL == New)
        {
            return false;
        }

    //如果为空链表,将头节点的Next指向新创建的节点    
    if (NULL == Head->Next)
    {
        Head->Next = New;
        return true;
    }
    //非空链表
    else
    {
        LkList_t *p = Head;             //将头节点地址赋值给p指针
        while (p->Data != Dest)
        {
            p = p->Next;
        }
        New->Next = p->Next;
        p->Next = New;   
    }
}

删除节点

1.删除首节点

2.删除尾节点

3.删除指定节点

//删除首节点
bool LkListHeadDel(LkList_t *Head)
{
    //判断是否为空链表
    if (NULL == Head->Next)
    {
        return false;
    }
    else
    {  
        LkList_t *p;                        
        p = Head->Next;

        Head->Next = p->Next;               //头节点的Next指向第二个节点
        p->Next = NULL;                     //首节点的Next赋值为NULL
        free(p);                            //释放首节点

        return true;
    }
}



//删除尾节点
bool LkListTailDel(LkList_t *Head)
{
    //判断是否为空链表
    if (NULL == Head->Next)
    {
        return false;
    }
    else
    {  
        LkList_t *p1 = Head;                //记录尾节点的前一个地址  
        LkList_t *p2 = Head->Next;          //记录尾节点的地址

        while (p2->Next != NULL)
        {
            p1 = p2;
            p2 = p2->Next;
        }
        
        p1->Next = NULL;                    //当前倒数第二个节点指向NULL,成为尾节点

        free(p2);                           //释放尾节点

        return true;
    }
}



//指定位置删除节点
bool LkListDestDel(LkList_t *Head , DataType_t Dest)
{
    //判断是否为空链表
    if (NULL == Head->Next)
    {
        return false;
    }
    else
    {
        LkList_t *p1 = Head;                //记录前一个节点的地址
        LkList_t *p2 = Head->Next;          //记录删除节点的地址

        //判断是否p->Data == Dest
        while (p2->Data != Dest)
        {
            p1 = p2;                        
            p2 = p2->Next;
        }
        
        p1->Next = p2->Next;                //将删除节点的Next,赋值给前一个节点
        p2->Next = NULL;                    //将删除节点的Next指向空
        
        free(p2);                           //释放该节点

        return true;
    }
}

遍历链表

//遍历链表
void LkListPrint(LkList_t *Head)
{
    LkList_t *p = Head;                 
    //打印整个链表
    while (p->Next != NULL)
    {
        p = p->Next;
        printf("Data=%d\n",p->Data);
    }
    
}
posted @ 2025-10-10 14:57  小黄花w  阅读(5)  评论(0)    收藏  举报