【数据结构】单链表相关操作

前言

单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

今天来一起学习单链表的相关操作

参考代码:

linklist.h:

#ifndef __LIST_H__
#define __LIST_H__

#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <assert.h>

typedef int DataType;

//不带头结点单链表
typedef struct Node
{
    DataType data;
    struct Node* pNext;
}Node,List,*pNode,*pList;

//初始化
void InitList(pList* pplist);
//打印
void PrintList(pList pplist);
//销毁链表
void DestoryList(pList* pplist);

//尾插
void  PushBack(pList* pplist, DataType d);
//尾删
void PopBack(pList* pplist);
//头插
void  PushFront(pList* pplist, DataType d);
//头删
void PopFront(pList* pplist);

//任意插
void Insert(pList* pplist,pNode pos, DataType d);
//任意删除
void Erase(pList* pplist,pNode pos);

//删除指定元素
void ReMove(pList* pplist, DataType d);
//删除指定元素 (法二)
void ReMove_OP(pList* pplist, DataType d);
//删除指定所有元素
void ReMoveAll(pList* pplist, DataType d);


//查找
pNode Find(pList pplist,DataType d);
//清空
void Clear(pList* pplist);
//链表大小
int Size(pList pplist);

#endif//__LIST_H__

linklist.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "LinkList.h"

//初始化
//改变传地址,不改变传值
void InitList(pList* pplist)
{
    assert(pplist);
    *pplist = NULL;
}
//打印
//改变传地址,不改变传值
void PrintList(pList pplist)
{
    //值传递不需要断言
    pNode pCur = pplist;
    while (pCur)
    {               
        printf("%d ",pCur->data);
        pCur = pCur->pNext;
    }
    printf("\n");

}
//销毁链表
void DestoryList(pList* pplist)
{
    pNode pDel = NULL;
    assert(pplist);
    while (*pplist)
    {
        pDel = *pplist;
        *pplist = pDel->pNext;
        free(pDel);
        pDel = NULL;
    }
    *pplist = NULL;
    printf("销毁成功\n");
}
//开辟新节点
static pNode BuyNode(DataType d)
{
    pNode tmp = (pNode)malloc(sizeof(Node));
    if (NULL == tmp)
    {
        perror("malloc faile");
        return NULL;
    }
    tmp->data = d;
    tmp->pNext = NULL;
    return tmp;

}
//尾插 (1.检查链表是否存在
//      2.存在为空直接插入
//      3.存在不为空先找到最后节点)
void  PushBack(pList* pplist, DataType d)
{
    pNode pNewNode = NULL;
    //判断是否存在
    assert(pplist);

    pNewNode = BuyNode(d);
    if (NULL == pNewNode)
    {
        exit(EXIT_FAILURE);
    }
    //为空直接插入
    if (NULL == *pplist)
    {
        *pplist = pNewNode;
    }
    //存在不为空找到最后节点
    else
    {
        pNode pCur = *pplist;
        while (pCur->pNext)
        {
            pCur = pCur->pNext;
        }
        pCur->pNext = pNewNode;

    }

}
//尾删(1.空链表返回
//      2.只有一个直接删
//      3.多个找到最后一个删除 )
void PopBack(pList* pplist)
{
    //判断链表是否存在
    assert(pplist);
    // 1.空链表返回
    if (NULL == *pplist)
    {
        return;
    }
    // 2.只有一个直接删
    else if (NULL == (*pplist)->pNext)
    {
        free(*pplist);
        *pplist = NULL;

    }
    // 3.多个找到倒数第二个删除
    else
    {
        pNode pCur = *pplist;
        while (pCur->pNext->pNext)
        {
            pCur = pCur->pNext;
        }
        free(pCur->pNext);
        pCur->pNext = NULL;
    }
}
//头插
void  PushFront(pList* pplist, DataType d)
{
    pNode pNewNode = NULL;
    assert(pplist);
    pNewNode = BuyNode(d);

    if (NULL == pNewNode)
    {
        return;
    }

    pNewNode->pNext = *pplist;
    *pplist = pNewNode;
}
//头删
void PopFront(pList* pplist)
{
    pNode pDel = NULL;
    assert(pplist);

    if (NULL == *pplist)
    {
        return;
    }

    pDel = *pplist;
    *pplist = pDel->pNext;
    free(pDel);
    pDel = NULL;
}


//任意插
void Insert(pList* pplist,pNode pos, DataType d)
{
    pNode pCur = NULL;
    pNode pNewNode = NULL;
    assert(pplist);

    if ((NULL == *pplist) || (pos == NULL))
    {
        return;
    }

    pNewNode = BuyNode(d);
    if (NULL == pNewNode)
    {
        return;
    }
    ////插入节点后面
    //pNewNode->pNext = pos->pNext;
    //pos->pNext = pNewNode;

    //插入节点前面
    //第一个节点
    if (pos == (*pplist))
    {
        pNewNode->pNext = pos;
        (*pplist) = pNewNode;
    }
    else  //多节点
    {
        pCur = *pplist;
        while (pCur && pCur->pNext != pos)
        {
            pCur = pCur->pNext;
        }
        if (pCur)
        {
            pNewNode->pNext = pCur->pNext;
            pCur->pNext = pNewNode;

        }
    }

}
//任意删除
void Erase(pList* pplist, pNode pos)
{
    pNode pCur = NULL;
    assert(pplist);
    if ((NULL == *pplist) || (pos == NULL))
    {
        return;
    }
    if (pos == *pplist)
    {
        PopFront(pplist);
    }
    else
    {
        pNode pCur = *pplist;
        while (pCur && pCur->pNext != pos)
        {
            pCur = pCur->pNext;
        }
        if (pCur)
        {
            pCur->pNext = pos->pNext;
            free(pos);
            pos = NULL;
        }
    }

}

//删除指定元素 (法一)
void ReMove(pList* pplist, DataType d)
{
    pNode pPre = NULL;
    pNode pCur = NULL;
    assert(pplist);

    if (*pplist == NULL)
    {
        return;
    }

    pCur = *pplist;
    while (pCur)
    {
        if (pCur->data == d)
        {
            if (pCur == (*pplist))
            {
                PopFront(pplist);
            }
            else
            {
                pPre->pNext = pCur->pNext;
                free(pCur);
                pCur = NULL;

            }
            return;
        }
        else
        {
            pPre = pCur;
            pCur = pCur->pNext;
        }
    }

}

//删除指定元素 (法二)
void ReMove_OP(pList* pplist, DataType d)
{
    pNode pos = NULL;
    assert(pplist);

    if (*pplist == NULL)
    {
        return;
    }

    //值传递
    pos = Find(*pplist, d);

    if (pos)
    {
        //址传递
        Erase(pplist,pos);
    }
}



//删除指定所有元素
void ReMoveAll(pList* pplist, DataType d)
{
    pNode pPre = NULL;
    pNode pCur = NULL;
    assert(pplist);

    if (*pplist == NULL)
    {
        return;
    }

    pCur = *pplist;
    while (pCur)
    {
        if (pCur->data == d)
        {
            if (pCur == (*pplist))
            {
                PopFront(pplist);
                pCur = *pplist;
            }
            else
            {
                pPre->pNext = pCur->pNext;
                free(pCur);
                pCur = pPre->pNext;

            }
        }
        else
        {
            pPre = pCur;
            pCur = pCur->pNext;
        }
    }

}

//查找
pNode Find(pList pplist,DataType d)
{
    pNode pCur = NULL;
    assert(pplist);

    pCur = pplist;
    while (pCur)
    {
        if (d == pCur->data)
        {
            return pCur;
        }
        pCur = pCur->pNext;
    }
    return NULL;


}
//清空
void Clear(pList* pplist)
{
    pNode pDel = NULL;
    assert(pplist);
    while (*pplist)
    {
        pDel = *pplist;
        *pplist = pDel->pNext;
        free(pDel);
        pDel = NULL;
    }
    printf("清空成功");

}
//链表大小
int Size(pList pplist)
{
    pNode pCur = NULL;
    int count = 0;
    assert(pplist);

    pCur = pplist;
    while (pCur)
    {
        count++;
        pCur = pCur->pNext;
    }
    return count;


}

test.c:

#define _CRT_SECURE_NO_WARNINGS 1

#include "LinkList.h"

pList plist = NULL;



void testpushback()
{
    PushBack(&plist,2);
    PushBack(&plist,5);
    PushBack(&plist,8);
    PushBack(&plist,6);
    PushBack(&plist,9);

    PrintList(plist);
}

void testpopback()
{
    PushBack(&plist, 2);
    PushBack(&plist, 5);
    PushBack(&plist, 8);
    PushBack(&plist, 6);
    PushBack(&plist, 9);

    PrintList(plist);
    PopBack(&plist);
    PrintList(plist);
    PopBack(&plist);
    PrintList(plist);

}
void testpushfront()
{
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 2);
    PushFront(&plist, 0);
    PushFront(&plist, 9);
    PrintList(plist);
}

void testpopfront()
{
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 2);
    PushFront(&plist, 0);
    PushFront(&plist, 9);
    PrintList(plist);


    PopFront(&plist);
    PrintList(plist);

    PopFront(&plist);
    PrintList(plist);
}

void testinsert()
{
    pNode pos = NULL;
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);
    pos = Find(plist,5);
    if (pos)
    {
        Insert(&plist, pos ,4);
        PrintList(plist);

    }


}
void testerase()
{

    pNode pos = NULL;
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);
    pos = Find(plist, 7);
    if (pos)
    {
        Erase(&plist, pos);
        PrintList(plist);

    }

}
void testfind()
{
    pNode POS = NULL;
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);

    if (Find(plist, 0) != NULL)
    {       
        POS = Find(plist, 0);
    }
    else
    {
        printf("没找到");
        return;
    }

    printf("%d",POS->data);

}
void testclear()
{
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);
    Clear(&plist);

}
void testsize()
{
    int i = 0;
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);

    i = Size(plist);
    printf("%d\n",i);

}

void testremove()
{
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 7);
    PushFront(&plist, 9);
    PrintList(plist);

    ReMove(&plist, 5);
    ReMove_OP(&plist, 9);
    PrintList(plist);


}

void testremoveall()
{
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 5);
    PushFront(&plist, 9);
    PushFront(&plist, 6);
    PushFront(&plist, 5);
    PushFront(&plist, 6);
    PushFront(&plist, 5);
    PrintList(plist);

    ReMoveAll(&plist, 5);
    ReMoveAll(&plist, 6);
    PrintList(plist);

}
int main()
{
    InitList(&plist);
    //testpushback();
    //testpopback();
    //testpushfront();
    //testpopfront();
    //testinsert();
    //testerase();
    //testfind();
    //testremove();
    testremoveall();
    //testclear();
    //testsize();

    DestoryList(&plist);
    system("pause");
    return 0;
}

结语

天道酬勤

猜你喜欢

转载自blog.csdn.net/qq_41035588/article/details/80920119