简单介绍线性表以及如何实现双链表

yizhihongxing
  1. 线性表的简介:

线性表是一类数据结构,其特点是数据元素之间存在一种线性关系。换句话说,线性表可以看作是一组有顺序的数据元素的集合,其中每个元素最多只有一个前驱和一个后继。(注:链表也是线性表的一种)

线性表的常见实现方式有数组和链表两种。

  1. 双向链表的实现:

双向链表是一种常见的链式存储结构,每个节点除了存储数据之外,还包括指向前驱和后继节点的指针。在操作链表时,我们可以通过这些指针实现对链表中任意节点的访问、插入和删除等操作。

下面是一个如何实现双向链表的代码示例:

typedef struct Node{
    int data;  
    struct Node *prev;  //指向前驱节点的指针
    struct Node *next;  //指向后继节点的指针
}Node;

Node* CreateDblList(int arr[], int n){  //创建双向链表
    Node *head, *tail, *p;
    head = (Node*)malloc(sizeof(Node));
    tail = head;
    for(int i=0; i<n; i++){
       p = (Node*)malloc(sizeof(Node));
       p->data=arr[i];
       p->prev=tail;
       p->next=NULL;
       tail->next=p;
       tail=p;
    }
    head->prev=NULL;
    return head;
}

void ShowDblList(Node *p){  //打印双向链表
    while(p->next!=NULL){
        p=p->next;
        printf("%d ", p->data);
    }
    printf("\n");
}

void InsertDblList(Node *p, int i, int x){  //在双向链表中插入节点
    Node *q=p;
    for(int j=0; j<i-1; j++) q=q->next;
    Node *t=(Node*)malloc(sizeof(Node));
    t->data=x;
    t->prev=q;
    t->next=q->next;
    if(q->next) q->next->prev=t;
    q->next=t;
}

void DeleteDblList(Node *p, int i){  //删除双向链表中的指定节点
    Node *q=p;
    for(int j=0; j<i-1; j++) q=q->next;
    q->prev->next=q->next;
    if(q->next) q->next->prev=q->prev;
    free(q);
}

接下来对上述代码做简单说明:

  • 结构体 Node 表示双向链表的每个节点,包含数据域 data,以及指向前驱节点和后继节点的指针 prevnext
  • 函数 CreateDblList 表示创建一个双向链表,传入参数为数组 arr 和数组长度 n,返回值为双向链表的头结点指针。
  • 函数 ShowDblList 表示打印双向链表,传入参数为头结点指针。
  • 函数 InsertDblList 表示在双向链表中插入指定节点,传入参数为头结点指针、插入位置 i 和插入值 x
  • 函数 DeleteDblList 表示删除双向链表中的指定节点,传入参数为头结点指针和待删除节点位置 i

下面是一个基于上述代码的示例:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node{
    int data;
    struct Node *prev;
    struct Node *next;
}Node;

Node* CreateDblList(int arr[], int n){
    Node *head, *tail, *p;
    head = (Node*)malloc(sizeof(Node));
    tail = head;
    for(int i=0; i<n; i++){
       p = (Node*)malloc(sizeof(Node));
       p->data=arr[i];
       p->prev=tail;
       p->next=NULL;
       tail->next=p;
       tail=p;
    }
    head->prev=NULL;
    return head;
}

void ShowDblList(Node *p){
    while(p->next!=NULL){
        p=p->next;
        printf("%d ", p->data);
    }
    printf("\n");
}

void InsertDblList(Node *p, int i, int x){
    Node *q=p;
    for(int j=0; j<i-1; j++) q=q->next;
    Node *t=(Node*)malloc(sizeof(Node));
    t->data=x;
    t->prev=q;
    t->next=q->next;
    if(q->next) q->next->prev=t;
    q->next=t;
}

void DeleteDblList(Node *p, int i){
    Node *q=p;
    for(int j=0; j<i-1; j++) q=q->next;
    q->prev->next=q->next;
    if(q->next) q->next->prev=q->prev;
    free(q);
}

int main(){
    int a[5] = {1, 2, 3, 4, 5};
    Node *L = CreateDblList(a, 5);

    printf("Original doubly linked list:\n");
    ShowDblList(L);

    printf("Insert value '6' into index '2':\n");
    InsertDblList(L, 2, 6);
    ShowDblList(L);

    printf("Delete value in index '4':\n");
    DeleteDblList(L, 4);
    ShowDblList(L);

    return 0;
}

以上代码示例中,我们通过 CreateDblList 函数创建了一个原始的双向链表,包含五个节点,值分别为 1,2,3,4,5;然后通过 InsertDblList 函数,我们在索引为 2 的位置插入了一个值为 6 的新节点;最后,我们通过 DeleteDblList 函数,将索引为 4 的节点删除。可以看到,通过双向链表的相关操作,我们可以实现动态的节点插入和删除,从而满足各种实际应用场景的需求。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简单介绍线性表以及如何实现双链表 - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Pycharm 文件更改目录后,执行路径未更新的解决方法

    以下是详细讲解“Pycharm 文件更改目录后,执行路径未更新的解决方法”的完整攻略。 问题描述 在PyCharm中,如果你更改了某个Python脚本所在的目录,有时候会出现执行路径未更新的情况,在运行程序时可能会遇到ImportError等错误。这是因为PyCharm运行程序时,默认使用的是原始目录,而非你最新的修改后的目录。 解决方案 解决方法就是修改运…

    other 2023年6月27日
    00
  • 什么是ip地址?ip地址基础知识介绍

    什么是IP地址?IP地址基础知识介绍 1. IP地址的定义 IP地址(Internet Protocol Address)是用于在互联网上唯一标识设备的一组数字。它是互联网协议(IP)的一部分,用于在网络中定位和识别设备。IP地址可以用于识别计算机、服务器、路由器等网络设备。 2. IP地址的结构 IP地址由32位或128位二进制数字组成,通常以点分十进制(…

    other 2023年7月29日
    00
  • python之mysqldb

    以下是详细讲解“Python之MySQLdb的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: Python之MySQLdb攻略 MySQLdb是Python中一个用于连接和操作MySQL数据库的模块。本攻略将介绍MySQLdb的安装和使用步骤。 步骤一:安装MySQLdb 可以使用以下命令在Ubuntu系统中安装MySQLdb: su…

    other 2023年5月10日
    00
  • Spring中使用事务嵌套时需要警惕的问题分享

    Spring中使用事务嵌套时需要警惕的问题分享 在Spring中,事务嵌套是一种常见的技术,用于处理复杂的业务逻辑。然而,使用事务嵌套时需要注意一些问题,以确保事务的正确性和一致性。本文将详细讲解这些问题,并提供两个示例说明。 1. 事务传播行为 在Spring中,事务传播行为定义了事务方法与其他事务方法的关系。当一个事务方法调用另一个事务方法时,事务传播行…

    other 2023年7月28日
    00
  • web目录下不应该存在多余的程序(安全考虑)

    为了确保网站的安全性,我们需要在服务器上遵守一些基本的安全规则,其中之一就是禁止在web目录下存在多余的程序。这是因为恶意攻击者可能会利用这些程序进行攻击,从而使我们的网站面临风险。 以下是一些可以帮助你实现这个目标的攻略: 1. 移动或删除不必要的文件 首先,你需要检查web目录下所有的文件,确定没有任何多余的程序存在。如果有,你需要考虑移动或删除它们以避…

    other 2023年6月27日
    00
  • 用标准c++实现string与各种类型之间的转换

    实现string与各种类型之间的转换,需要用到标准C++库中的stringstream类。stringstream是一个基于字符串的流,能够实现将字符串与各种类型之间的相互转换。 实现步骤如下: 第一步:包含头文件 包含头文件,并使用namespace std。 #include <sstream> using namespace std; 第二…

    other 2023年6月26日
    00
  • windows8系统账号自动登录默认设置2种方式

    Windows 8系统支持两种方式设置自动登录:本地计算机账号自动登录和Microsoft账号自动登录。下面分别详细讲解这两种方式的设置步骤。 本地计算机账号自动登录 打开“运行”对话框,方法:按下“Win + R”组合键,或者在开始菜单中搜索“运行”。 输入“netplwiz”命令并点击“确定”按钮。 在“用户账户”窗口中,取消勾选“要使用本计算机,用户必…

    other 2023年6月27日
    00
  • iPhone XR升级iOS13.5.1玩游戏卡顿掉帧解决方法

    iPhone XR升级iOS13.5.1玩游戏卡顿掉帧解决方法攻略 如果你是iPhone XR用户,升级了iOS13.5.1系统后玩游戏会出现卡顿掉帧的问题,这里提供一些解决方法。以下是完整攻略的步骤和示例说明: 步骤1:清空后台应用 iOS系统会在后台保存一些应用,占用着系统资源。清空后台应用可以释放一些资源,提高游戏性能。 示例说明: 双击iPhone …

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部