C语言超详细i讲解双向链表

C语言超详细讲解双向链表

什么是双向链表

双向链表是一个动态数据结构,它由一系列的节点构成,每个节点分为三部分:数据域、指向前驱节点的指针和指向后继节点的指针。双向链表支持在任意位置插入或删除节点,与数组相比,它具有更好的灵活性和效率。

如何实现双向链表

定义节点

typedef struct DNode {
    int data;
    struct DNode* prev;
    struct DNode* next;
}DNode, *DLinkList;

创建节点

//创建节点
DNode* create_node(int data) {
    DNode* node = (DNode*)malloc(sizeof(DNode));
    node->data = data;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

插入节点

头部插入节点

//头部插入节点
void insert_head(DLinkList* head, DNode* node) {
    if (node == NULL) {
        return;
    }
    node->next = *head;
    node->prev = NULL;
    if (*head != NULL) {
        (*head)->prev = node;
    }
    *head = node;
}

尾部插入节点

//尾部插入节点
void insert_tail(DLinkList* head, DNode* node) {
    if (node == NULL) {
        return;
    }
    if (*head == NULL) {
        *head = node;
        node->prev = NULL;
        node->next = NULL;
    }
    else {
        DNode* p = *head;
        while (p->next != NULL) {
            p = p->next;
        }
        node->prev = p;
        node->next = NULL;
        p->next = node;
    }
}

按位置插入节点

//按位置插入节点
void insert_pos(DLinkList* head, DNode* node, int pos) {
    if (node == NULL) {
        return;
    }
    if (*head == NULL || pos <= 1) {
        node->prev = NULL;
        node->next = *head;
        if (*head != NULL) {
            (*head)->prev = node;
        }
        *head = node;
    }
    else {
        DNode* p = *head;
        int i = 1;
        while (p->next != NULL && i < pos-1) {
            p = p->next;
            i++;
        }
        node->prev = p;
        node->next = p->next;
        if (p->next != NULL) {
            p->next->prev = node;
        }
        p->next = node;
    }
}

删除节点

删除头部节点

//删除头部节点
void delete_head(DLinkList* head) {
    if (*head != NULL) {
        DNode* p = *head;
        *head = (*head)->next;
        if (*head != NULL) {
            (*head)->prev = NULL;
        }
        free(p);
    }
}

删除尾部节点

//删除尾部节点
void delete_tail(DLinkList* head) {
    if (*head != NULL) {
        DNode* p = *head;
        while (p->next != NULL) {
            p = p->next;
        }
        if (p->prev != NULL) {
            p->prev->next = NULL;
        }
        else {
            //删除头部节点
            *head = NULL;
        }
        free(p);
    }
}

按位置删除节点

//按位置删除节点
void delete_pos(DLinkList* head, int pos) {
    if (*head != NULL && pos >= 1) {
        if (pos == 1) {
            //删除头部节点
            delete_head(head);
        }
        else {
            DNode* p = *head;
            int i = 1;
            while (p->next != NULL && i < pos) {
                p = p->next;
                i++;
            }
            if (i == pos && p != NULL) {
                if (p->prev != NULL) {
                    p->prev->next = p->next;
                }
                if (p->next != NULL) {
                    p->next->prev = p->prev;
                }
                free(p);
            }
        }
    }
}

示例说明

插入节点示例

//创建双向链表
DLinkList head = NULL;
int n, i, data;
printf("请输入节点个数:");
scanf("%d", &n);
for (i = 1; i <= n; i++) {
    printf("请输入第%d个节点的数据:", i);
    scanf("%d", &data);

    //创建节点
    DNode* node = create_node(data);

    //头部插入节点
    //insert_head(&head, node);

    //尾部插入节点
    insert_tail(&head, node);

    //按位置插入节点
    //insert_pos(&head, node, i);
}

//遍历双向链表
DNode* p = head;
printf("双向链表元素:");
while (p != NULL) {
    printf("%d ", p->data);
    p = p->next;
}

删除节点示例

//创建双向链表
DLinkList head = NULL;
int n, i, data;
printf("请输入节点个数:");
scanf("%d", &n);
for (i = 1; i <= n; i++) {
    printf("请输入第%d个节点的数据:", i);
    scanf("%d", &data);

    //创建节点
    DNode* node = create_node(data);

    //头部插入节点
    insert_head(&head, node);

    //尾部插入节点
    //insert_tail(&head, node);

    //按位置插入节点
    //insert_pos(&head, node, i);
}

//删除双向链表中第3个节点
delete_pos(&head, 3);

//遍历双向链表
DNode* p = head;
printf("双向链表元素:");
while (p != NULL) {
    printf("%d ", p->data);
    p = p->next;
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言超详细i讲解双向链表 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • C语言编程中常见的五种错误及对应解决方案

    C语言编程中常见的五种错误及对应解决方案 C语言作为一门古老而广泛应用的编程语言,因为其高效、灵活、强大的特性受到了广泛的关注和使用。但是,在编写C程序时,常常会遇到各种错误,本文将介绍C语言编程中常见的五种错误及对应的解决方案,以帮助读者更好地避免这些错误并提高编程能力。 1. 语法错误(Syntax Error) 语法错误指在编译程序时发生的错误,通常是…

    C 2023年5月23日
    00
  • C语言朴素模式匹配算法实例代码

    以下是“C语言朴素模式匹配算法实例代码”的完整攻略。 什么是朴素模式匹配算法? 朴素模式匹配算法是一种简单的字符串匹配算法,它基于蛮力法: 遍历主串中的每个字符,每找到一个位置与模式串的第一个字符匹配,就从后续位置开始一个个比较主串和模式串中的字符是否相同,如果某个字符不匹配,则回到主串中对应的位置重新比较。 朴素模式匹配算法的实现原理 下面是C语言实现朴素…

    C 2023年5月22日
    00
  • 详细分析C++ 信号处理

    详细分析C++信号处理 什么是信号处理? 信号处理是一种处理外部事件的方法。在Linux环境下,当一个进程接收到某种事件信号时,操作系统会发送一个信号给该进程。通过信号处理函数,进程可以对该信号进行处理。 如何在C++中进行信号处理? 在C++中,可以通过POSIX标准的signal()函数来设置信号处理函数。以下是使用signal()函数的代码示例: #i…

    C 2023年5月23日
    00
  • Java内部类和异常类的概念以及使用

    Java内部类(Inner Class)是定义在其他类中的类。内部类具有比普通类更多的访问权限,可以访问其外部类的私有属性和方法。Java内部类可以分为四种类型:成员内部类、局部内部类、匿名内部类和静态内部类。 举个例子:假设有一个外部类叫做OuterClass,它有一个私有属性叫做privateVar,内部类叫做InnerClass。下面是一个成员内部类的…

    C 2023年5月23日
    00
  • Python特殊属性property原理及使用方法解析

    好的。首先,我们来讲解一下Python中用于面向对象编程的特殊属性property的原理及使用方法。 Python特殊属性property原理及使用方法解析 什么是property? 在Python中,一个对象的属性(包括实例属性和类属性)可以通过一组方法来操作。例如,对于一个Person类,可以通过p.name来获取或设置其姓名属性。但是,有些属性是需要一…

    C 2023年5月22日
    00
  • c#版json数据解析示例分享

    下面就详细讲解“C#版JSON数据解析示例分享”的完整攻略。 什么是JSON? JSON是JavaScript Object Notation的简称,是一种轻量级的数据交换格式,易于使用并且易于阅读和编写。在网络应用中,它通常用于与服务器进行交换数据。 JSON格式的数据通常使用大括号{}括起来,其中包含一个或多个键值对。其中,键是字符串,值可以是数字、字符…

    C 2023年5月23日
    00
  • C Primer Plus (7.12) 編程練習

    /*C Primer Plus (7.11) 3*/ 1 #include<stdio.h> 2 int main() 3 { 4 double weight,height; 5 printf(“Please enter your weight and height.\n”); 6 printf(“Weight (pound):”); 7 sca…

    C语言 2023年4月18日
    00
  • C语言 strstr()函数

    当你需要在一个字符串中查找另一个字符串的时候,strstr()函数是一个非常有用的工具。它可以帮助你查找一个字符串中是否包含另一个指定的字符串,并返回匹配的位置。 语法 strstr()函数的语法如下: char* strstr(const char* str1, const char* str2); 该函数接受两个参数:str1和str2。str1是主字符…

    C 2023年5月9日
    00
合作推广
合作推广
分享本页
返回顶部