链表的增、删、查、找

基本结构

typedef int DataType;

typedef struct SListNode
{
struct SListNode* _next;
DataType _data;
}SListNode;

链表结构分为两部分,一部分是数据域,存放的是节点的数据部分,另一部分是指针域,保存下一节点的地址

新建节点

和动态顺序表不一样,每次只开辟一个节点的空间,将其节点的指针域赋为空

代码:

SListNode* BuySListNode(DataType x)
{
    SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode));
    if (NewNode==NULL)
    {
        perror("申请失败");
        exit(EXIT_FAILURE);

    }
    NewNode->_data = x;
    NewNode->_next = NULL;


    return NewNode;
}

打印链表

动态顺序表是通过下标来进行访问,而链表是通过指针访问到每一个节点,当某一节点的指针域为空时,说明链表到尾

代码:

void SListPrint(SListNode* pHead)
{


    while (pHead != NULL)
    {
        printf("%d  ", pHead->_data);
        pHead = pHead->_next;
    }
    printf("\n");
}

链表的头插(过程如下图)

这里写图片描述

代码:



void SListPushFront(SListNode** ppHead, DataType x)
{

    if ((*ppHead) == NULL)
    {
        SListNode *cur = BuySListNode(x);
        *ppHead = cur;
    }
    else
    {
        SListNode *cur = BuySListNode(x);
        cur->_next = *ppHead;
        *ppHead = cur;


     }

}

链表头删(过程如下图)

这里写图片描述

代码:

void SListPopFront(SListNode** ppHead)
{
    if (*ppHead == NULL)
    {
        printf("list is empty\n");
    }

    else
    {
        SListNode *cur = *ppHead;
        free(cur);
        *ppHead = (*ppHead)->_next;

    }

}

尾插(过程与头插想类似在这里不在画图)

代码:

void SListPushBack(SListNode** ppHead, DataType x)
{
    assert(ppHead);
    SListNode *cur = *ppHead;
    if (*ppHead == NULL)
    {
        *ppHead = BuySListNode(x);
    }
    else
    {
        while (cur->_next != NULL)
        {
            cur = cur->_next;
        }

        cur->_next = BuySListNode(x);

    }


}

尾删

代码:

void SListPopBack(SListNode** ppHead)
{

    SListNode *cur = *ppHead;
    if (*ppHead == NULL)
    {
        printf("List is empty\n");
    }
    else if ((*ppHead)->_next == NULL)
    {
        free(*ppHead);
        *ppHead = NULL;
    }
    else
    {
        while (cur->_next->_next != NULL)
        {
            cur = cur->_next;
        }

        free(cur->_next);
        cur->_next = NULL;
    }

}

任意位置插入(指头插)

在这里需要注意几点:
1)链表为空时,只需调用头插即可
2)链表有一个及以上节点时,需注意保存该位置的前一位置,将其与前一位置相连

这里写图片描述

代码:

void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
    assert(*ppHead);

    SListNode* prev = *ppHead;//记录pos位置的前一个节点
    SListNode* cur = *ppHead;//头结点

    if (pos == cur)
    {
        SListPushFront(ppHead, x);
    }
    else
    {
        while (prev->_next != pos)
        {
            prev = prev->_next;
        }
        SListNode* NewNode = BuySListNode(x);
        NewNode->_next = prev->_next;
        prev->_next = NewNode;
    }   
}

任意位置删除(删除方法类似头插,不在画图)

代码:

void SListErase(SListNode** ppHead, SListNode* pos)
{

    if (*ppHead == NULL)
    {
        printf("list is empty\n");
    }
    else 
    {
        if (pos == *ppHead)
        {

            SListNode *cur = *ppHead;
            (*ppHead) = (*ppHead)->_next;
            free(cur);
        }
        else if (pos == NULL)
        {
            SListPopBack(&pos);
        }
        else
        {
            SListNode* prev = *ppHead;
            while (prev->_next != pos)
            {
                prev = prev->_next;
            }

            prev->_next = pos->_next;
            free(pos);
        }

    }




}

下面给出完整代码及测试用例:

SeqList.c:

  SListNode* list;


//新建一个节点
SListNode* BuySListNode(DataType x)
{
    SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode));
    if (NewNode==NULL)
    {
        perror("申请失败");
        exit(EXIT_FAILURE);

    }
    NewNode->_data = x;
    NewNode->_next = NULL;


    return NewNode;
}



//打印链表
void SListPrint(SListNode* pHead)
{


    while (pHead != NULL)
    {
        printf("%d  ", pHead->_data);
        pHead = pHead->_next;
    }
    printf("\n");
}

//释放节点
void SListDestory(SListNode** ppHead)
{
    assert(ppHead);
    free(*ppHead);
    *ppHead = NULL;

}


//尾插
void SListPushBack(SListNode** ppHead, DataType x)
{
    assert(ppHead);
    SListNode *cur = *ppHead;
    if (*ppHead == NULL)
    {
        *ppHead = BuySListNode(x);
        (*ppHead)->_next = NULL;
    }
    else
    {
        while (cur->_next != NULL)
        {
            cur = cur->_next;
        }

        cur->_next = BuySListNode(x);

    }


}


//尾删
void SListPopBack(SListNode** ppHead)
{

    SListNode *cur = *ppHead;
    if (*ppHead == NULL)
    {
        printf("List is empty\n");
    }
    else if ((*ppHead)->_next == NULL)
    {
        free(*ppHead);
        *ppHead = NULL;
    }
    else
    {
        while (cur->_next->_next != NULL)
        {
            cur = cur->_next;
        }
        free(cur->_next);
        cur->_next = NULL;
    }

}


//头插
void SListPushFront(SListNode** ppHead, DataType x)
{

    if ((*ppHead) == NULL)
    {
        SListNode *cur = BuySListNode(x);
        *ppHead = cur;
    }
    else
    {
        SListNode *cur = BuySListNode(x);
        cur->_next = *ppHead;
        *ppHead = cur;

    }

}

//头删
void SListPopFront(SListNode** ppHead)
{
    if (*ppHead == NULL)
    {
        printf("list is empty\n");
    }

    else
    {
        SListNode *cur = *ppHead;
        *ppHead = (*ppHead)->_next;
        free(cur);

    }

}


//任意位置插入
void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
    assert(ppHead);
    //assert(pos);
    SListNode* prev = *ppHead;//记录pos位置的前一个节点
    SListNode* cur = *ppHead;//头结点

    if (pos == cur)
    {
        SListPushFront(ppHead, x);
    }
    else
    {
        while (prev->_next != pos)
        {
            prev = prev->_next;
        }
        SListNode* NewNode = BuySListNode(x);
        NewNode->_next = prev->_next;
        prev->_next = NewNode;
    }   
}


//查找
SListNode* SListFind(SListNode* pHead, DataType x)
{
    assert(pHead);
    SListNode *cur = pHead;
    while (cur != NULL)
    {
        if (cur->_data == x)
        {
            return  cur;
        }
        cur = cur->_next;
    }
    return NULL;

}

//任意位置删除
void SListErase(SListNode** ppHead, SListNode* pos)
{

    if (*ppHead == NULL)
    {
        printf("list is empty\n");
    }
    else 
    {
        if (pos == *ppHead)
        {

            SListNode *cur = *ppHead;
            (*ppHead) = (*ppHead)->_next;
            free(cur);
        }
        else if (pos == NULL)
        {
            SListPopBack(&pos);
        }
        else
        {
            SListNode* prev = *ppHead;
            while (prev->_next != pos)
            {
                prev = prev->_next;
            }

            prev->_next = pos->_next;
            free(pos);
        }

    }




}

test.c

//测试尾插
void TestSListPushBack()
{

    list = NULL;
    SListPushBack(&list, 0);
    SListPushBack(&list, 1);
    SListPushBack(&list, 2);
    SListPushBack(&list, 3);
    SListPushBack(&list, 4);
    SListPushBack(&list, 5);
    SListPrint(list);

}



//测试尾删
void TestSListPopBack(SListNode** ppHead)
{
    list = NULL;
    SListPushBack(&list, 0);
    SListPushBack(&list, 1);
    SListPushBack(&list, 2);
    SListPushBack(&list, 3);
    SListPushBack(&list, 4);
    SListPushBack(&list, 5);
    SListPrint(list);


    SListPopBack(&list);
    SListPopBack(&list);
    SListPopBack(&list);
    SListPopBack(&list);
    SListPopBack(&list);
    SListPopBack(&list);

    SListPrint(list);

}

//测试头插
void TestSListPushFront()
{
    list = NULL;
    SListPushFront(&list, 0);
    SListPushFront(&list, 1);
    SListPushFront(&list, 2);
    SListPushFront(&list, 3);
    SListPushFront(&list, 4);
    SListPrint(list);



}

//测试头删
void TestSListPopFront()
{
    list = NULL;
    SListPushFront(&list, 0);
    SListPushFront(&list, 1);
    SListPushFront(&list, 2);
    SListPushFront(&list, 3);
    SListPushFront(&list, 4);
    SListPrint(list);

    SListPopFront(&list);
    SListPopFront(&list);
    SListPopFront(&list);
    SListPopFront(&list);
    SListPopFront(&list);

    SListPrint(list);



}



//测试查找
void  TestSListFind()
{

    list = NULL;
    SListPushFront(&list, 0);
    SListPushFront(&list, 1);
    SListPushFront(&list, 2);
    SListPushFront(&list, 3);
    SListPushFront(&list, 4);





    SListNode* cur = SListFind(list, 3);
    printf("%d\n", cur->_data);

}

//测试任意位置插入
void TestSListInsest()
{


    list = NULL;
    SListPushFront(&list, 0);
    SListPushFront(&list, 1);
    SListPushFront(&list, 2);
    SListPushFront(&list, 3);
    SListPushFront(&list, 4);
    SListPrint(list);


    SListNode *ret = SListFind(list, 0);
    SListInsest(&list, ret, 78);
    ret = SListFind(list, 4);
    SListInsest(&list, ret, 78);
    ret = SListFind(list, 2);
    SListInsest(&list, ret, 78);

    SListPrint(list);

}

//测试任意位置删除
void TestSListErase(SListNode** ppHead, SListNode* pos)
{
    list = NULL;
    SListPushFront(&list, 0);
    SListPushFront(&list, 1);
    SListPushFront(&list, 2);
    SListPushFront(&list, 3);
    SListPushFront(&list, 4);
    SListPrint(list);


    SListNode *ret = SListFind(list, 4);
    SListInsest(&list, ret, 23);
    SListPrint(list);




    ret = SListFind(list, 4);
    SListErase(&list, ret);
    ret = SListFind(list, 23);
    SListErase(&list, ret);
    ret = SListFind(list, 0);
    SListErase(&list, ret);
    SListPrint(list);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值