关于双向链表的增删查改

              List.c  

 #include "List.h"

LTNode* BuyListNode(LTDataType x)
{
    LTNode* node = (LTNode*)malloc(sizeof(LTNode));
    if (node == NULL)
    {
        perror("malloc fail");
        exit(-1);//终止程序
        return;
    }
    node->next = NULL;
    node->prev = NULL;
    node->data = x;
    return node;
}

LTNode* ListInit()
{
    LTNode* phead = BuyListNode(-1);
    phead->next = phead;
    phead->prev = phead;
    return phead;
}

//void ListInit(LTNode** pphead)
//{
//    *pphead = BuyListNode(-1);
//    (*pphead)->next = *pphead;
//    (*pphead)->prev = *pphead;
//}

void ListPrint(LTNode* phead)
{
    assert(phead);

    LTNode* cur = phead->next;
    while (cur != phead)
    {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
}

//尾插
void ListPushBack(LTNode* phead, LTDataType x)
{
    assert(phead);

    LTNode* newnode = BuyListNode(x);
    LTNode* tail = phead->prev;
    tail->next = newnode;
    newnode->prev = tail;
    newnode->next = phead;
    phead->prev = newnode;

    //注意!
    //可以用任意插==>哨兵位前一个就是尾节点
    //ListInsert(phead, x);
}

//头插
void ListPushFront(LTNode* phead, LTDataType x)
{
    assert(phead);
    
    LTNode* newnode = BuyListNode(x);
    LTNode* next = phead->next;//后面就不需要考虑顺序了
    // phead newnode next
    next->prev = newnode;
    newnode->next = next;
    newnode->prev = phead;
    phead->next = newnode;

    //注意!如果不写next,有严格的顺序
    // phead->next->prev = newnode;
    // newnode->next = phead->next;前两句不能换
    // phead->next = newnode;
    // newnode->prev = phead;

    //再注意!
    //可以直接用任意插
    //ListInsert(phead->next, x);
}

//检查是否为空(只有哨兵位)
bool ListEmpty(LTNode* phead)
{
    assert(phead);
    return phead->next == phead;
}

//尾删
void ListPopBack(LTNode* phead)
{
    assert(phead);

    assert(!ListEmpty(phead));//防止链表为空
    //assert(phead->next != phead);

    LTNode* tail = phead->prev;
    LTNode* tailPrev = tail->prev;

    free(tail);

    tailPrev->next = phead;
    phead->prev = tailPrev;


    //再注意!
    //可以直接用任意删
    //ListErase(phead->prev);
}

//头删
void ListPopFront(LTNode* phead)
{
    assert(phead);
    assert(!ListEmpty(phead));//防止链表为空
    //assert(phead->next != phead);

    LTNode* top = phead->next;

    phead->next = top->next;
    top->next->prev = phead;
    free(top);


    //再注意!
    //可以直接用任意删
    //ListErase(phead->next);
}


//在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x)
{
    assert(pos);

    LTNode* prev = pos->prev;
    LTNode* newnode = BuyListNode(x);

    // prev newnode pos
    prev->next = newnode;
    newnode->prev = prev;
    newnode->next = pos;
    pos->prev = newnode;
}

//删除pos位置的节点
void ListErase(LTNode* pos)
{
    assert(pos);

    LTNode* prev = pos->prev;
    LTNode* next = pos->next;

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

//数元素
int ListSize(LTNode* phead)
{
    assert(phead);
    LTNode* cur = phead->next;
    int size = 0;
    while (cur != phead)//循环回去就结束了
    {
        ++size;
        cur = cur->next;
    }
    return size;
}

//双向链表销毁
void ListDestory(LTNode* phead)
{
    assert(phead);
    LTNode* cur = phead->next;
    int size = 0;
    while (cur != phead)//循环回去就结束了
    {
        LTNode* next = cur->next;
        ListErase(cur);
        cur = next;
    }

    free(phead);
    phead = NULL;//好习惯
}

              List.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
//带头(哨兵位)双向循环链表

typedef int LTDataType;
typedef struct ListNode
{
    struct ListNode* next;
    struct ListNode* prev;
    LTDataType data;
}LTNode;

//void ListInit(LTNode** pphead);太复杂了
//初始化
LTNode* ListInit();
//打印
void ListPrint(LTNode* phead);
//尾插头插
void ListPushBack(LTNode* phead, LTDataType x);
void ListPushFront(LTNode* phead, LTDataType x);

//检查是否为空(只有哨兵位)
bool ListEmpty(LTNode* phead);
//尾删头删
void ListPopBack(LTNode* phead);
void ListPopFront(LTNode* phead);

//上来先写这个!!!!!!!
    //在pos位置之前插入x
void ListInsert(LTNode* pos, LTDataType x);
    //删除pos位置的节点
void ListErase(LTNode* pos);

//数元素
int ListSize(LTNode* phead);

//双向链表销毁
void ListDestory(phead);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值