双向链表基本操作及顺序和链表总结

简介: 双向链表基本操作及顺序和链表总结

基本函数实现

链表声明

typedef int DLTDataType;

typedef struct DListNode
{
   
   
    struct DListNode* next;
    struct DListNode* prev;
    DLTDataType val;
}DLTNode;

总的函数实现声明


//申请新的节点
DLTNode* CreateLTNode(DLTDataType x);
//初始化
DLTNode* DLTInit();
//打印
void DLTPrint(DLTNode* phead);
//头插头删尾插尾删
void DLTPushBack(DLTNode* phead, DLTDataType x);
void DLTPopBack(DLTNode* phead);
void DLTPushFront(DLTNode* phead, DLTDataType x);
void DLTPopFront(DLTNode* phead);
//找x的位置
DLTNode* DLTFind(DLTNode* phead, DLTDataType x);
//在pos前面插入
void DLTInsert(DLTNode* pos, DLTDataType x);
//删除pos位置
void DLTErase(DLTNode* pos);
//销毁链表
void DLTDestroy(DLTNode* phead);

创建一个节点


DLTNode* CreateLTNode(DLTDataType x)
{
   
   
    DLTNode* newnode = (DLTNode*)malloc(sizeof(DLTNode));
    if (newnode == NULL)
    {
   
   
        perror("malloc fail");
        exit(-1);
    }
    newnode->val = x;
    newnode->prev = NULL;
    newnode->next = NULL;
    return newnode;
}

初始化链表


DLTNode* DLTInit()
{
   
   
    DLTNode* phead = CreateLTNode(-1);
    phead->next = phead;
    phead->prev = phead;
    return phead;
}

打印


void DLTPrint(DLTNode* phead)
{
   
   
    assert(phead);
    printf("哨兵卫<=>");

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

尾插


//第一种尾插方式
//void DLTPushBack(DLTNode* phead, DLTDataType x)
//{
   
   
//    assert(phead);
//    DLTNode* tail = phead->prev;
//    DLTNode* newnode = CreateLTNode(x);
//
//    tail->next = newnode;
//    newnode->prev = tail;
//    newnode->next = phead;
//    phead->prev = newnode;
//}

//第二种尾插方式
void DLTPushBack(DLTNode* phead, DLTDataType x)
{
   
   
    assert(phead);
    DLTInsert(phead, x);
}

尾删


//第一种尾删
//void DLTPopBack(DLTNode* phead)
//{
   
   
//    assert(phead);
//    assert(phead->next != phead);
//
//    DLTNode* tail = phead->prev;
//    DLTNode* tailPrev = tail->prev;
//    free(tail);
//    tailPrev->next = phead;
//    phead->prev = tailPrev;
//}

//第二种尾删
void DLTPopBack(DLTNode* phead)
{
   
   
    assert(phead);
    assert(phead->next != phead);

    DLTErase(phead->prev);
}

头插


//第一种头插方式
//void DLTPushFront(DLTNode* phead, DLTDataType x)
//{
   
   
//    assert(phead);
//    DLTNode* newnode = CreateLTNode(x);
//
//    newnode->next = phead->next;
//    phead->next->prev = newnode;
//    phead->next = newnode;
//    newnode->prev = phead;
//}

//第二种头插方式
//void DLTPushFront(DLTNode* phead, DLTDataType x)
//{
   
   
//    assert(phead);
//    DLTNode* newnode = CreateLTNode(x);
//    DLTNode* first = phead->next;
//
//    phead->next = newnode;
//    newnode->prev = phead;
//    newnode->next = first;
//    first->prev = newnode;
//}

//第三种头插方式
void DLTPushFront(DLTNode* phead, DLTDataType x)
{
   
   
    assert(phead);

    DLTInsert(phead->next, x);
}

头删


第一种头删
//void DLTPopFront(DLTNode* phead)
//{
   
   
//    assert(phead);
//    assert(phead->next != phead);
//
//    DLTNode* first = phead->next;
//    DLTNode* second = first->next;
//    phead->next = second;
//    second->prev = phead;
//    free(first);
//    first = NULL;
//}

//第二种头删
void DLTPopFront(DLTNode* phead)
{
   
   
    assert(phead);
    assert(phead->next != phead);

    DLTErase(phead->next);
}

查找


DLTNode* DLTFind(DLTNode* phead, DLTDataType x)
{
   
   
    assert(phead);

    DLTNode* cur = phead->next;
    while (cur != phead)
    {
   
   
        if (cur->val == x)
        {
   
   
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

pos前插入


//在pos前面插入
void DLTInsert(DLTNode* pos, DLTDataType x)
{
   
   
    assert(pos);

    DLTNode* posPrev = pos->prev;
    DLTNode* newnode = CreateLTNode(x);

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

删除pos位置


//删除pos位置
void DLTErase(DLTNode* pos)
{
   
   
    assert(pos);

    DLTNode* posNext = pos->next;
    DLTNode* posPrev = pos->prev;

    posPrev->next = posNext;
    posNext->prev = posPrev;
    free(pos);
    pos = NULL;
}

销毁链表


void DLTDestroy(DLTNode* phead)
{
   
   
    assert(phead);

    DLTNode* cur = phead->next;
    while (cur != phead)
    {
   
   
        DLTNode* next = cur->next;
        free(cur);
        cur = next;
    }
    free(phead);
}

顺序表和链表总结

image.png
上方的链表指的是双向链表,顺序表指的是数组顺序表。

目录
相关文章
|
6月前
|
存储 算法 C语言
线性表,双向链表,静态链表,循环链表(约瑟夫环)(上)
线性表,双向链表,静态链表,循环链表(约瑟夫环)
78 5
|
3月前
|
存储 Java
|
4月前
链表8(法二考试专用)7-8 sdut-C语言实验-双向链表
链表8(法二考试专用)7-8 sdut-C语言实验-双向链表
20 0
|
4月前
sdut 链表 8 -----7-8 sdut-C语言实验-双向链表
sdut 链表 8 -----7-8 sdut-C语言实验-双向链表
19 0
|
5月前
|
存储 缓存
【海贼王的数据航海】链表—双向链表
【海贼王的数据航海】链表—双向链表
28 0
|
5月前
|
存储 算法 前端开发
【C/数据结构与算法】:链表的实现(单向链表+双向链表)
【C/数据结构与算法】:链表的实现(单向链表+双向链表)
28 0
|
5月前
|
算法
数据结构和算法学习记录——线性表之双向链表(下)-头插函数、头删函数、查找函数、pos位置之前插入结点、pos位置删除结点及其复用、销毁链表函数
数据结构和算法学习记录——线性表之双向链表(下)-头插函数、头删函数、查找函数、pos位置之前插入结点、pos位置删除结点及其复用、销毁链表函数
29 0
|
6月前
|
缓存 算法
【数据结构】----链表--双向链表
【数据结构】----链表--双向链表
42 0
|
6月前
|
存储 C语言
线性表,双向链表,静态链表,循环链表(约瑟夫环)(下)
线性表,双向链表,静态链表,循环链表(约瑟夫环)
72 6
|
6月前
|
C语言
数据结构:5、链表之双向链表
数据结构:5、链表之双向链表
47 0