【数据结构】链表操作C实现

数据类型的定义
typedef int DataType; 

typedef struct ListNode
{ 
    DataType data; 
    struct ListNode *next; 
} ListNode;

链表的初始化和销毁

链表的初始化—–>构造一条空链表
链表的销毁—–>销毁每个结点

//初始化
void ListInit(ListNode **pFirst)
{
    *pFirst = NULL; 
}
//销毁
void ListDestory(ListNode **pFirst)
{
    ListNode *cur = NULL;
    ListNode *del = NULL;
    assert(*pFirst);
    cur = *pFirst;
    while(cur->next != NULL)
    {
        del = cur;
        cur = cur->next;
        free(del);
    }
    free(cur);
}

打印链表
void ListPrint(ListNode **pFirst)
{
    ListNode *cur = NULL;
    assert(*pFirst != NULL);
    cur = *pFirst;
    while(cur != NULL)
    {
        printf("%d ",cur->data);
        cur = cur->next;
    }
    printf("\n");
}

查找

按值查找,如果找到了返回第一个找到的结点指针,如果没找到,返回NULL。代码如下:

ListNode *ListFind(ListNode **pFirst, DataType data)
{
    ListNode *cur = NULL;
    assert(*pFirst != NULL);
    cur = *pFirst;
    while(cur != NULL)
    {
        if(cur->data == data)
        {
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

增加数据

在增加数据前,需要一个函数来创建一个新结点,函数返回新结点的地址,通过改变链表中结点的next指向来将新结点加入到链表中。代码如下:

ListNode *CreateNode(DataType data)
{
    ListNode *NewNode = (ListNode *)malloc(sizeof(DataType));
    NewNode->data = data;
    NewNode->next = NULL;
    return NewNode;
}
尾插

这里写图片描述
代码如下:

void ListPushBack(ListNode **pFirst, DataType data)
{
    ListNode *cur = NULL;
    //如果链表为空
    if(*pFirst == NULL)
    {
        *pFirst = CreateNode(data);
        return ;
    }
    //链表不为空
    cur = *pFirst;
    while(cur->next != NULL)
    {
        cur = cur->next;
    }
    cur->next = CreateNode(data);
}
头插

这里写图片描述
代码如下:

void ListPushFront(ListNode **pFirst, DataType data)
{
    ListNode *cur = NULL;
    //如果链表为空
    if(*pFirst == NULL)
    {
        *pFirst = CreateNode(data);
        return ;
    }
    //链表不为空
    cur = *pFirst;
    *pFirst = CreateNode(data);
    (*pFirst)->next = cur;
}
指定位置插入(插入到结点前)

这里写图片描述
代码如下:

void ListInsert(ListNode **pFirst, ListNode *pos, DataType data)
{
    ListNode *cur = NULL;
    ListNode *NewNode = NULL;
    assert(*pFirst != NULL);
    if(pos == NULL)
        return ;
    //如果在第一个元素位置前插入,调用头插函数
    if(pos == *pFirst)
    {
        ListPushFront(pFirst, data);
    }
    cur = *pFirst;
    NewNode = CreateNode(data);
    while(cur->next != pos)
    {
        cur = cur->next;
    }
    cur->next = NewNode;
    NewNode->next = pos;
}

删除数据
尾删

这里写图片描述
代码如下:

void ListPopBack(ListNode **pFirst)
{
    ListNode *cur = NULL;
    ListNode *del = NULL;
    assert(*pFirst != NULL);
    //如果链表只有一个元素
    if((*pFirst)->next == NULL)
        *pFirst = NULL;
    //如果链表有多个元素
    cur = *pFirst;
    while(cur->next->next != NULL)
    {
        cur = cur->next;
    }
    del = cur->next->next;
    cur->next = NULL;
    free(del);
}
头删

这里写图片描述
代码如下:

void ListPopFront(ListNode **pFirst)
{
    ListNode *del = NULL;
    assert(*pFirst != NULL);
    //如果链表只有一个元素
    if((*pFirst)->next == NULL)
    {
        *pFirst = NULL;
    }
    //如果链表有多个元素
    del = *pFirst;
    *pFirst = (*pFirst)->next; 
    //free(del);
}
删除给定结点

这里写图片描述
代码如下:

void ListErase(ListNode **pFirst, ListNode *pos)
{
    ListNode *del = NULL;
    ListNode *cur = NULL;
    assert(*pFirst != NULL);
    //如果给定结点不存在
    if(pos == NULL)
        return ;
    //如果给定结点是第一个元素 调用头删函数
    if(pos == *pFirst)
    {
        ListPopFront(pFirst);
        return ;
    }
    //如果给定结点是最后一个 调用尾删函数
    else if(pos->next == NULL)
    {
        ListPopBack(pFirst);
        return ;
    }
    //如果给定结点是除首尾外元素
    cur = *pFirst;
    while(cur->next != pos)
    {
        cur = cur->next;
    }
    cur->next = cur->next->next;
    //free(pos);
}
删除指定元素

分为两种情况:
1、如果要删除元素是第一个元素,就调用头删函数;
2、如果要删除元素不是第一个元素,遍历该链表,找到第一个等于要删除元素的结点,将该结点的前一个结点的next指向该结点的下一个结点,即删除了该元素。
代码如下:

void ListRemove(ListNode **pFirst, DataType data)
{
    ListNode *cur = NULL;
    ListNode *del = NULL;
    assert(*pFirst != NULL);
    //如果删除的元素为第一个元素
    if((*pFirst)->data == data)
    {
        ListPopFront(pFirst);
        return ;
    }
    cur = *pFirst;
    while(cur != NULL)
    {
        if(cur->next->data == data)
        {
            del = cur->next;
            cur->next = cur->next->next;
            return ;
        }
        cur = cur->next;
    }
}
删除所有指定元素

这里写图片描述

void ListRemoveAll(ListNode **pFirst, DataType data)
{
    ListNode *cur = NULL;
    assert(*pFirst != NULL);
    cur = *pFirst;
    while(cur != NULL)
    {
        if((*pFirst)->data == data)
        {
            *pFirst = (*pFirst)->next;
        }
        else if(cur->next->data == data)
        {
            cur->next = cur->next->next;
        }
        cur = cur->next;
    }
}

上述内容均为学习过程中的总结,如有不足之处,请指正

猜你喜欢

转载自blog.csdn.net/cottonrose_orange/article/details/82687055
今日推荐