带头双向链表

定义

链表的每个结点包含了两个指针域,一直指针域指向前面,一个指针域指向后面,称为双向链表,带有头节点就是带头双向链表。

双向链表存储结构

typedef int STDatatype;
typedef struct ListNode
{
    struct ListNode* prev;//指向前一个
    struct ListNode* next;//指向后一个
    STDatatype data;
}LNode;

双向链表基本操作

//初始化
LNode* ListInit();
//头插
void ListPushFront(LNode* phead, STDatatype x);
//尾插
void ListPushBack(LNode* phead, STDatatype x);
//判空
bool ListEmpty(LNode* phead);
//头删
void ListPopFront(LNode* phead);
//尾删
void ListPopBack(LNode* phead);
//查找
LNode* ListFind(LNode* phead, STDatatype x);
//打印
void ListPrint(LNode* phead);
//在pos之前插入
void ListPrevInsert(LNode* pos, STDatatype x);
//在pos之后插入
void ListNextInsert(LNode* pos, STDatatype x);
//删除pos
void ListDeletePos(LNode* pos);

创建结点

LNode* BuyListNode(STDatatype x)
{
    LNode* newnode = (LNode*)malloc(sizeof(LNode));
    if (newnode == NULL)
    {
        perror("malloc fail");
        return NULL;
    }
    newnode->data = x;
    newnode->next = NULL;
    newnode->next = NULL;
    return newnode;
}

打印

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

初始化

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

头插

void ListPushFront(LNode* phead, STDatatype x)
{
    assert(phead);
    LNode* newnode = BuyListNode(x);
    LNode* tail = phead->next;
    newnode->next = tail;
    tail->prev = newnode;
    newnode->prev = phead;
    phead->next = newnode;
}

尾插

void ListPushBack(LNode* phead, STDatatype x)
{
    assert(phead);
    LNode* newnode = BuyListNode(x);
    LNode* cur = phead->prev;
    cur->next = newnode;
    newnode->prev = cur;
    newnode->next = phead;
    phead->prev = newnode;
}

判空

bool ListEmpty(LNode* phead)
{
    assert(phead);
    return phead->next == phead && phead->prev == phead;
}

头删

void ListPopFront(LNode* phead)
{
    assert(phead);
    assert(!ListEmpty(phead));
    LNode* first = phead->next;
    LNode* tail = first->next;
    phead->next = tail;
    tail->prev = phead;
    free(first);
}

尾删

void ListPopBack(LNode* phead)
{
    assert(phead);
    assert(!ListEmpty(phead));
    LNode* tail = phead->prev;
    LNode* prev = tail->prev;
    prev->next = tail->next;
    phead->prev = prev;
}

查找

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

在pos之前插入

void ListPrevInsert(LNode* pos, STDatatype x)
{
    assert(pos);
    LNode* newnode = BuyListNode(x);
    LNode* prev = pos->prev;
    prev->next = newnode;
    newnode->prev = prev;
    newnode->next = pos;
    pos->prev = newnode;
}

在pos之后插入

void ListNextInsert(LNode* pos, STDatatype x)
{
    assert(pos);
    LNode* newnode = BuyListNode(x);
    LNode* tail = pos->next;
    tail->prev = newnode;
    newnode->next = tail;
    pos->next = newnode;
    newnode->prev = pos;
}

删除pos

void ListDeletePos(LNode* pos)
{
    assert(pos);
    LNode* prev = pos->prev;
    LNode* tail = pos->next;
    prev->next = tail;
    tail->prev = prev;
    free(pos);
}

销毁

void ListDestroy(LNode** phead)
{
    assert(phead);
    LNode* cur = (*phead)->next;
    while (cur != (*phead))
    {
        LNode* tail = cur->next;
        free(cur);
        cur = tail;
    }
    free(*phead);
    *phead = NULL;
}

如果有不足或是错误,欢迎大神指点。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值