单链表的基本操作

单链基本操作的部分思维导图

这里写图片描述

代码

头文件.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;

typedef struct ListNode{
    struct ListNode *_pNext;
    DataType _data;
}Node,*PNode;


void ListNodeInit(PNode* PHead);    //初始化单链表
PNode BuyNode(DataType data);   //创建新节点
void ListPushBack(PNode* PHead, DataType data); //尾插
void ListPopBack(PNode* PHead); //  尾删
void ListPushFront(PNode* PHead, DataType data);    //头插
void ListPopFront(PNode* PHead);//头删
PNode ListFind(PNode PHead, DataType data); // 在链表中查找值为data的元素,找到后返回值为data的结点 
void ListInsert(PNode* pHead, PNode pos, DataType data);    // 在pos位置插入值为data的结点
void ListErase(PNode* pHead, PNode pos);    // 删除pos位置的结点
int ListEmpty(PNode pHead); //判断链表是否为空
int SListSize(PNode pHead); // 获取链表中值data的结点 
void SListDestroy(PNode* pHead);    // 销毁聊表


PNode FindNode(PNode PHead, int pos);   //查找已经存在的链表内是否存在第pos位结点
void ListPrint(PNode PHead);    //打印结点内容

功能模块

#include"Apr_14.h"

//初始化链表
void ListNodeInit(PNode* pHead)
{
    assert(pHead);
    *pHead =  NULL;
}

//申请节点
PNode BuyNode(DataType data)
{
    PNode NewNode = (PNode)malloc(sizeof(Node));    //sizeof(Node)  内部一定是结点的大小,而不是指针的大小

    if (NULL == NewNode)    //虽然几率很小,但是万一申请失败程序就会崩溃,所以记得加容错机制
    {
        assert(0);
        return NULL;
    }

    NewNode->_data = data;
    NewNode->_pNext = NULL;
    return NewNode;
}

//尾插
void ListPushBack(PNode* PHead, DataType data)
{
    assert(PHead);  //PHead内存的链表的地址,如果为空,则说明链表不存在

    if (NULL == *PHead) //检查链表是否为空
        *PHead = BuyNode(data);
    else
    {
        PNode pCur = *PHead;

        //找出最后一个结点
        //while(pCur)也是寻找最后一个结点的一种方法,不过要保存它的前一个结点
        while (pCur->_pNext)
        {
            pCur = pCur->_pNext;
        }
        pCur->_pNext = BuyNode(data);
    }
}

//尾删
void ListPopBack(PNode* PHead)
{
    PNode Del = NULL;   
    PNode prev = NULL;
    assert(PHead);

    if (NULL == *PHead) //链表为空,没有结点需要删除
    {
        return;
    }

    else if ((*PHead)->_pNext)
    {
        Del = *PHead;
        while (Del->_pNext)
        {
            prev = Del;
            Del = Del->_pNext;
        }
        free(Del);
        prev->_pNext = NULL;
    }
    else if (*PHead)
    {
        free((*PHead));
        *PHead = NULL;
    }
}

//头插
void ListPushFront(PNode* PHead, DataType  data)
{
    assert(PHead);

    PNode NewNode;
    if (NULL == *PHead)
    {
        NewNode = BuyNode(data);
        NewNode->_pNext = NULL;
        *PHead = NewNode;
    }
    else
    {
        NewNode = BuyNode(data);
        NewNode->_pNext = *PHead;
        *PHead = NewNode;
    }
}

//头删
void ListPopFront(PNode* PHead)
{
    PNode Del = (*PHead);
    PNode Pre = NULL;

    assert(PHead);

    if (NULL == PHead)
    {
        return;
    }

    if ((*PHead)->_pNext)
    {   
        *PHead = (*PHead)->_pNext;
        free(Del);
        Del = NULL;
    }
    else if (*PHead)
    {
        free(Del);
        *PHead = NULL;
    }
}

// 在链表中查找值为data的元素,找到后返回值为data的结点 
PNode ListFind(PNode PHead, DataType data)
{
    PNode PCur = NULL;
    assert(PHead);

    if (NULL == PHead)
        return NULL;

    PCur = PHead;

    while (PCur)
    {
        if (PCur->_data == data)
        {
            return PCur;
        }
        PCur = PCur->_pNext;
    }

    return NULL;
}

// 在pos位置插入值为data的结点
void ListInsert(PNode* PHead, PNode pos, DataType data)
{
    assert(PHead);

    if (NULL == (*PHead))   //  链表为空,自动头插
        ListPushFront(PHead, data);
    if (pos == NULL)    //插入位置为空,缺省为头插
        ListPushFront(PHead, data);
    else if (!pos->_pNext)  //插入位置为链表末尾
    {
        ListPushBack(PHead, data);  
    }
    else
    {
        PNode PCur = NULL;
        PNode NewNode = NULL;
        DataType tmp;

        NewNode = BuyNode(data);    
        NewNode->_pNext = pos->_pNext;
        pos->_pNext = NewNode;
        tmp = pos->_data;
        pos->_data = data;
        NewNode->_data = tmp;
    }

}

// 删除pos位置的结点
void ListErase(PNode* PHead, PNode pos)
{
    PNode Del = NULL;
    PNode PPre = NULL;
    assert(PHead);

    if (NULL == *PHead || NULL == pos)
        return;

    Del = *PHead;
    while (Del && Del != pos)
    {
        PPre = Del;
        Del = Del->_pNext;
    }
    if (Del->_pNext != NULL)
    {
        PPre->_pNext = Del->_pNext;
        free(Del);
        Del = NULL;
    }
    else
    {
        free(Del);
        PPre->_pNext = NULL;
    }
}

int ListEmpty(PNode pHead)
{
    if (NULL == pHead)
    {
        printf("链表为空\n");
        return 0;
    }
    else
    {
        return 1;
    }
}

// 销毁链表
void SListDestroy(PNode* PHead)
{
    PNode Des;
    assert(PHead);

    if (NULL == (PHead))
        return;

    Des = *PHead;
    while (Des)
    {
        Des = (*PHead)->_pNext;
        free(*PHead);
        if (Des)
            (*PHead) = Des;
    }
    *PHead = NULL;
}



//查找链表中是否存在第pos个结点
PNode FindNode(PNode PHead, int pos)
{
    PNode PCur = NULL;
    PNode PPre = NULL;
    if (NULL == PHead)
    {
        return NULL;
    }

    PCur = PHead;
    while (pos && PCur)
    {
        PPre = PCur;
        PCur = PCur->_pNext;
        pos--;
    }

    if (pos == 0)
        return PPre;
    else
        return NULL;
}


//打印
void ListPrint(PNode PHead)
{
    if (NULL == PHead)
        return;

    while (PHead)
    {
        printf("%d ", PHead->_data);
        PHead = PHead->_pNext;
    }
    printf("\n");
}

测试文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Apr_14.h"

void TestPushOrPop()
{
    PNode PHead;
    ListNodeInit(&PHead);
    ListPushBack(&PHead, 6);
    ListPushBack(&PHead, 9);
    ListPushBack(&PHead, 8);
    ListPrint(PHead);
    ListPopBack(&PHead);
    ListPushBack(&PHead, 11);
    ListPrint(PHead);
    ListPopBack(&PHead);
    ListPushFront(&PHead, 3);
    ListPrint(PHead);
    ListPopFront(&PHead);
    ListPrint(PHead);
}

void TestListFind()
{
    PNode PHead;
    PNode tmp = NULL;
    ListNodeInit(&PHead);
    ListPushBack(&PHead, 6);
    ListPrint(PHead);
    ListPushBack(&PHead, 9);
    ListPushBack(&PHead, 8);
    ListPushFront(&PHead, 3);
    ListPushFront(&PHead, 7);
    ListPushFront(&PHead, 1);
    ListPrint(PHead);
    tmp = ListFind(PHead, 9);
    if (tmp)
    {
        printf("%d\n", tmp->_data);
    }
    tmp = FindNode(PHead, 3);
    if (tmp)
    {
        printf("%d\n", tmp->_data);
    }
    ListInsert(&PHead, tmp, 13);
    ListPrint(PHead);
    tmp = NULL;
    ListInsert(&PHead, tmp, 0);
    ListPrint(PHead);
    tmp = FindNode(PHead, 6);
    ListErase(&PHead, tmp);
    ListPrint(PHead);
    tmp = FindNode(PHead, 7);
    ListErase(&PHead, tmp);
    ListPrint(PHead);
    SListDestroy(&PHead);
}

int main()
{
    TestPushOrPop();
    TestListFind();
    system("pause");
    return 0;
}
阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zym1348010959/article/details/79961188
文章标签: 单链表
上一篇动态顺序表
下一篇关于链表的一些面试题总结
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭