双链表的基本操作

双链表的基本操作和单链表是相同的:增 、删、改
  • 头文件DList.H
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>

typedef int DataType;

typedef struct DList
{
    DataType data;

    struct DList *pPrev;
    struct DList *pNext;
}DList;

//创建一个新结点
DList * BuyNewNode(DataType data);

//初始化
void Init(DList ** ppHead);

//尾插
void PushBack(DList ** ppHead,DataType data);

//头插
void PushFront(DList **ppHead, DataType data);

//给定值插
void Insert(DList **ppHead, DList *pPos, DataType data);

//给定位置删
void Earse(DList **ppHead, DList *pPos);

//尾删
void PopBack(DList *pHead);

//头删
void PopFront(DList * pHead);

//给定结点删除,只删除遇到的第一个
void Remove(DList ** ppHead,DataType data);

//给定结点删除,删除所有的
void RemoveAll(DList ** ppHead, DataType data);

//查找
DList * Find(DList *pHead,DataType data);

//打印
void Print(DList *pHead);

//清空链表
void Clear(DList *pHead);

//销毁链表
void Destroy(DList **ppHead);
  • DList.c
#include"DList.h"

//创建一个新结点
DList * BuyNewNode(DataType data)
{
    DList * pNode;
    pNode = (DList *)malloc(sizeof (DList));
    assert(pNode);
    pNode->data = data;
    pNode->pPrev = NULL;
    pNode->pNext = NULL;
    return pNode;
}

//初始化
void Init(DList ** ppHead)
{
    //创建一个没有用的结点,构成双向循环的条件
    int no_use = 0;

    *ppHead = BuyNewNode(no_use);
    (*ppHead)->pNext = *ppHead;
    (*ppHead)->pPrev = *ppHead;
}

//尾插
void PushBack(DList **ppHead,DataType data)
{
    DList *pLast,*pNewNode;
    pNewNode = BuyNewNode(data);
    //尾插要找到最后一个结点
    pLast = (*ppHead)->pPrev;

    pNewNode->pNext = *ppHead;
    pNewNode->pPrev = pLast;
    pLast->pNext = pNewNode;
    (*ppHead)->pPrev = pNewNode;

}

//头插
void PushFront(DList **ppHead, DataType data)
{
    DList *pFirst, *pNewNode;
    pNewNode = BuyNewNode(data);

    //头插找第一个结点
    pFirst = (*ppHead)->pNext;

    pNewNode->pNext = pFirst;
    pNewNode->pPrev = *ppHead;
    pFirst->pPrev = pNewNode;
    (*ppHead)->pNext = pNewNode;
}

//给定结点插入
void Insert(DList **ppHead, DList *pPos, DataType data)
{
    DList *pNewNode,*pPrevpos;
    pNewNode = BuyNewNode(data);

    //找到前一个结点
    pPrevpos = pPos->pPrev;

    pNewNode->pNext = pPos;
    pNewNode->pPrev = pPrevpos;
    pPos->pPrev = pNewNode;
    pPrevpos->pNext = pNewNode;
}

//给定位置删
void Earse(DList **ppHead, DList *pPos)
{
    DList *pPrePos,*pNext;
    pPrePos = pPos->pPrev;
    pNext = pPos->pNext;

    pPrePos->pNext = pNext;
    pNext->pPrev = pPrePos;
}

//尾删
void PopBack(DList * pHead)
{
    1.利用函数
    //Earse(&pHead, pHead->pPrev);

    //2.利用结点的操作
    DList *pLast, *pPrePos;
    pLast = pHead->pPrev;
    pPrePos = pLast->pPrev;
    pHead->pPrev = pPrePos;
    pPrePos->pNext = pHead;
}

//头删
void PopFront(DList *pHead)
{
    1.利用函数
    //Earse(&pHead, pHead->pNext);

    //2.结点删除
    DList *pFirst, *pSec;
    pFirst = pHead->pNext;
    pSec = pFirst ->pNext;
    pHead->pNext = pSec;
    pSec->pPrev = pHead;
    free(pFirst);
    pFirst = NULL;
}

//给定结点删除,只删除遇到的第一个
void Remove(DList ** ppHead, DataType data)
{
    DList * pNode;
    pNode = Find(*ppHead, data);
    if (pNode == NULL)
    {
        printf("输入数据不存在\n");
    }
    else
    {
        Earse(ppHead, pNode);

    }
}

//给定结点删除,删除遇到的所有
void RemoveAll(DList ** ppHead, DataType data)
{
    DList * pNode;
    while (Find(*ppHead, data))
    {
        pNode = Find(*ppHead, data);
        if (pNode == NULL)
        {
            printf("输入数据不存在\n");
        }
        else
        {
            Earse(ppHead, pNode);

        }
    }

}

//查找
DList * Find(DList * pHead,DataType data)
{
    DList *pNode;
    for (pNode = pHead->pNext; pNode != pHead; pNode = pNode->pNext)
    {
        if (pNode->data == data)
        {
            return pNode;
        }
    }
    return NULL;
}

//打印
void Print(DList *pHead)
{
    DList *pNode;
    pNode = pHead;
    printf("%2d->", pHead->data);
    for (pNode = pHead->pNext; pNode != pHead; pNode = pNode->pNext)
    {
        printf("%2d->", pNode->data);
    }
    printf("%2d", pHead->data);
    printf("\n");
}

//清空链表,只剩个头。这里不会对头结点造成改变,所以可以传入的是一级指针
void Clear(DList * pHead)
{
    DList * pNode,*pNext;
    for (pNode = pHead->pNext; pNode != pHead; pNode = pNext)
    {
        //释放
        pNext = pNode->pNext;
        free(pNode);
        pNode = NULL;
    }
    pHead->pNext = pHead;
    pHead->pPrev = pHead;
}

//销毁链表
void Destroy(DList **ppHead)
{
    Clear(*ppHead);
    free(*ppHead);
    *ppHead = NULL;
    printf("销毁成功\n");
}
  • Main.c
#include"DList.h"

void test()
{
    DList * DL;
    Init(&DL);  //初始化
    PushBack(&DL, 4);   //尾插
    PushBack(&DL, 5);   //尾插
    PushBack(&DL, 5);   //尾插
    PushBack(&DL, 4);   //尾插
    PushBack(&DL, 4);   //尾插
    PushBack(&DL, 5);   //尾插
    PushFront(&DL, 3);  //头插
    Print(DL);
    Insert(&DL, DL->pNext, 2);         //给定结点进行插入
    Print(DL);
    Earse(&DL, DL->pNext);
    Print(DL);
    PopBack(DL);        //尾删
    Print(DL);
    PopFront(DL);       //头删
    Print(DL);
    Remove(&DL, 3);     //删除遇到的第一个
    Print(DL);
    RemoveAll(&DL, 4);  //删除所有的
    Print(DL);
    Destroy(&DL);       //销毁
}

int main()
{
    test();
    return 0;
}
  • 结果如下图

这里写图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值