c语言带头双链表的基础操作

1. 创建一个双链表结点

typedef int ltdatatype;

typedef struct listnode
{
    int data;
    struct listnode* prev;//前驱节点
    struct listnode* next;//后驱结点
}ltnode;

2.创建一个新结点的函数


ltnode* ltbuynode(int x)//x是数据域
{
    ltnode* newnode = (ltnode*)malloc(sizeof(ltnode));
    if (newnode = NULL)
    {
        perror("malloc fail");
        exit(1);
    }

    newnode->data = x;
    newnode->next = NULL;
    newnode->prev = NULL;

    return newnode;
}

 3.双链表结点的初始化

ltnode* ltinit()
{
    ltnode* phead = ltbuynode(-1);
    return phead;
}

4.双链表的打印

void ltprint(ltnode* phead)
{
    ltnode* pcur = phead;
    //用遍历链表的方式打印
    assert(phead);
    ltnode* pcur = phead->next;//创建指针变量pcur指向头结点
    while (pcur != phead)
    {
        printf("%d->", pcur->data);
        pcur = pcur->next;
    }
    printf("\n");
}
 

5.双链表的尾插

void ltpushback(ltnode* phead, ltdatatype x)
{
    ltnode* newnode = ltbuynode(x);
    //phead phead->prev newnode
    newnode->next = phead;//
    newnode->prev = phead->prev;
    
    phead->prev->next = newnode;
    phead->prev = newnode;
}

 

6.双链表的头插

void ltpushfront(ltnode* phead, ltdatatype x)
{
    assert(phead);
    ltnode* newnode = lbuynode(x);

    //结点的连结
    newnode->next = phead->next;
    newnode->prev = phead;

    phead->next->prev = newnode;
    phead->next = newnode;
}
 

 7.双链表的尾删

void ltpopback(ltnode* phead)
{
    assert(phead);
    //链表不能为空(不能只有头结点)

    ltnode* del = phead->prev;
    ltnode* prev = del->prev;

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

    free(del);
    del = NULL;
}

8. 双链表的头删

//头删,不是删除头结点
void ltpopfront(ltnode* phead)

{
    assert(phead);
    assert(phead->next!=phead);
    ltnode* del = phead->next;
    ltnode* next = del->next;

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

    free(del);
    del = NULL;
}
 

9.双链表的结点查找

//结点查找
ltnode* ltfind(ltnode* phead, ltdatatype x)
{
    assert(phead);
    ltnode* pcur = phead->next;//遍历循环双链表的同时又不让它成为死循环,所以应该将pcur指向第一节点
    while (pcur != phead)//所以只要遍历到头结点,那么就停止遍历
    {
        if (pcur->data == x)//如果找到了
        {
            return pcur;
        }
        pcur = pcur->next;
    }
    return NULL;
}
 

10.双链表的指定节点之后插入数据

//指定位置pos之后插入数据
ltnode* ltfind(ltnode* pos, ltdatatype x)
{
    assert(pos);
    ltnode* newnode = ltbuynode(x);
    
    newnode->next = pos->next;
    newnode->prev = pos;

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

 

11.删除指定结点

//删除pos位置的数据
void lterase(ltnode* pos)
{
    assert(pos);

    pos->next->prev = pos->prev;
    pos->prev->next = pos->next;

    free(pos);
    pos->next;
}

 

12.双链表的销毁

void ltdestroy(ltnode* phead)
{
    assert(phead);
    ltnode* pcur = phead->next;
    while (pcur != phead)
    {
        free(pcur);//每遍历一次就删除一次
        pcur = pcur->next;
    }

    free(phead);
    phead = NULL;//因为是一级指针,所以这里phead为空以后实参的一级指针仍然没空,
    //所以如果实参时plist,那么经过此函数后仍要手动置空plist=NULL;

}

 

你可能感兴趣的:(c语言数据结构,c语言,数据结构,算法)