带头双向循环链表

在这里插入图片描述

链表

单向链表的缺陷

单链表的缺陷:1.查找的速度慢
2.不能从后往前找
3.找不到前驱
双链表的优势:把链表的删除和插入的时间复杂度从o(n)变成了o(1)

链表的结构在这里插入图片描述

两两组合,一共有8种链表在这里插入图片描述
在这里插入图片描述

带头双向循环链表的宏定义

typedef int LTDataType
typedef struct ListNode
{
    struct ListNode* next;
    struct ListNode* prve;
    LTDataType data;
}ListNode;

带哨兵位的双向循环链表的结构虽然复杂了,但是可操作性增加了。

常用接口

//创建节点的接口
ListNode* BuyListNode(LTDataType x);
//初始化哨兵位节点
ListNode* ListInit();
//摧毁链表
void ListDestory(ListNode*phead);
//尾插
void ListPushBack(ListNode* phead,LTDataType x);
//头插接口(传入的指针是哨兵位指针)
void ListPushFront(ListNode* phead,LTDatatype x);
//尾删接口
void ListPopBack(ListNode* phead);
//头删接口
void ListPopFront(ListNode* phead);
//打印链表
void Listprint(ListNode* phead);
//查找接口并具有修改作用
ListNode* ListFind(ListNode* phead,LTDataType x);
/pos位置之前插入x
void ListInsert(ListNode*pos,LTDataType x);
//删除pos位置的值
void ListErase(ListNode* pos);

创建节点接口

ListNode* BuyListNode(LTDataType x)
{
    ListNode* newnode=(ListNode*)malloc(sizeof(ListNode));
    newnode->data=x;
    newnode->next=NULL;
    newnode->prve=NULL;
    return newnode;
}

初始化哨兵位节点接口

ListNode* ListInit()
{
     //哨兵位的节点
     ListNode* phead=BuyListNode(0);
     phead->next=phead;
     phead->prve=phead;
     return phead;
}

摧毁链表接口

void ListDestory(ListNode*phead)
{
    assert(phead);
    ListNode* cur=phead->next;
    while(cur!=phead)
    {
        ListNode*next=cur->next;
        free(cur);
        cur=next;    
    }
    free(phead);
    phead=NULL;
}

尾插接口

void ListPushBack(ListNode* phead,LTDataType x)
{
    //将原链表的最后一个单元的地址存储在指针变量tail中
     ListNode*tail=phead->prev;
     //创建新的链表单元
     ListNode*newnode=BuyListNode(x);  
     tail->next=newnode;
     newnode->prev=tail;
     newnode->next=phead;
     phead->prev=newnode;
}

头插接口

void ListPushFront(ListNode* phead,LTDatatype x)
{
    assert(phead);
    //如果为空链表,那么phead->next==phead;
    ListNode* first=phead->next;
    ListNode*newnode=BuyListNode(x);
    phead->next=newnode;
    newnode->next=first;
    newnode->prev=phead;
    first->prev=newnode;
}

尾删接口

void ListPopBack(ListNode* phead)
{
    assert(phead);
    ListNode* tail=phead->prev;
    ListNode* prev=tail->prev;
    phead->prev=prev;
    prev->next=phead;
    free(tail);
    tail=NULL;
}

头删接口

void ListPopFront(ListNode* phead)
{
    assert(phead);
    assert(phead->next!=phead);
    ListNode* first=phead->next;
    ListNode*second=first->next;
    phead->next=first->next;
    second->prev=phead;
    free(first);
    first=NULL;
}

打印链表

void Listprint(ListNode* phead)
{
    ListNode* cur=phead->next;
    while(cur!=phead)
    {
         printf("%d",cur->data);
         cur=cur->next;    
    }
    free(cur);
    cur=NULL;
}

查找接口

ListNode* ListFind(ListNode* phead,LTDataType x)
{
    assert(phead);
    ListNode* cur=phead->next;
    while(cur!=phead)
    {
        if(cur->data==x)
        {
            return cur;        
        }  
        cur=cur->next;  
    }
    return NULL;
}

pos位置之前插入x

void ListInsert(ListNode*pos,LTDataType x)
{
    assert(pos);
    ListNode*prev=pos->prev;
    ListNode*newnode=BuyListNode(x);
    prev->next=newnode;
    newnode->prev=prev;
    newnode->next=pos;
    pos->prev=newnode;
}

删除pos位置的值

void ListErase(ListNode* pos)
{
    assert(pos);
    assert(pos!=phead);
     ListNode*prev=pos->prev;
     ListNode*next=pos->next;
     prev->next=next;
     next->prev=prev;
     free(pos);
     pos=NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

影中人lx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值