问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

链表-单链表的基本设计(C语言代码实现)

创作时间:
作者:
@小白创作中心

链表-单链表的基本设计(C语言代码实现)

引用
CSDN
1.
https://m.blog.csdn.net/qq_45398836/article/details/141531138

单链表是数据结构中一种常见的线性表实现方式,通过链式存储结构来组织数据。本文将详细介绍单链表的基本设计,包括结点的构成、初始化方法以及两种主要的创建方式:头插入法和尾插入法。

单链表概念&设计

单链表是一种链式存取的数据结构,链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。以“结点的序列”表示的线性表称作线性链表(单链表),单链表是链式存取的结构。

对于链表的每一个结点,我们使用结构体(struct)进行设计,其主要内容有:

  • DATA:数据元素,可以是你想要储存的任何数据格式,可以是数组,可以是int,甚至可以是结构体(这就是传说中的结构体套结构体)
  • NEXT:一个指针,其代表了一个可以指向的区域,通常是用来指向下一个结点,链表的尾部NEXT指向NULL(空),因为尾部没有任何可以指向的空间了

故,对于一个单链表的结点定义,可以代码描述成:

struct Node {
    int data;       //数据类型,你可以把int型的data换成任意数据类型,包括结构体struct等复合类型
    struct Node *next;          //单链表的指针域
}

单链表的初始化

同任何的结构,类型一样,链表也需要初始化操作,初始化是创建一个单链表的前置节点并向后逐步添加节点,一般来说,我们所谓的初始化单链表一般指的是申请结点的空间,同时对一个结点辅以空值(NULL),其代码可以表示为:

Node* L = (Node*)malloc(sizeof(Node));      //开辟空间
if(L==NULL){                     //判断是否开辟空间失败,这一步很有必要
    //exit(0);                  //开辟空间失败可以考虑直接结束程序
}

在这里我们有一个注意点,就是一定要记住判断是否开辟空间失败,虽然在很多试题中以及常用的环境提供的环境非常安全,几乎没有开辟失败的存在,但是也一定要养成判断是否开辟失败并且判断失败后执行代码,但在生产中由于未知的情况造成一旦空间开辟失败任然在继续执行代码,后果将不堪设想,因此养成这样的判断是很有必要的,在C++中可以使用try-catch这样的语句进行优化。

创建单链表(头插入法)

在初始化之后,就可以着手开始创建单链表了,单链表的创建分为头插入法和尾插入法两种,两者并无本质上的不同,都是利用指针指向下一个结点元素的方式进行逐个创建,只不过使用头插入法最终得到的结果是逆序的。

如图,为头插法的创建过程:

该方法从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即头结点之后。

LinkedList LinkedListCreatH() {
    L = (Node *)malloc(sizeof(Node));   //申请头结点空间
    L->next = NULL;                      //初始化一个空链表
    while(scanf("%d",&x) != EOF) {
        p = (Node *)malloc(sizeof(Node));   //申请新的结点
        p->next = L->next;     //将结点插入到表头
        L->next = p;
    }
}

创建单链表(尾插入法)

如图,为尾插入法的创建过程。

头插法建立单链表的算法虽然简单,但生成的链表中结点的次序和输入数据的顺序不一致。若希望两者次序一致,可采用尾插法。

该方法是将新结点逐个插入到当前链表的表尾上,为此必须增加一个尾指针 r, 使其始终指向当前链表的尾结点,否则就无法正确的表达链表。

LinkedList LinkedListCreatT() {
    L = (Node *)malloc(sizeof(Node));   //申请头结点空间
    L->next = NULL;                  //初始化一个空链表
    r = L;                          //r始终指向终端结点,开始时指向头结点
    while(scanf("%d",&x) != EOF) {
        p = (Node *)malloc(sizeof(Node));   //申请新的结点
        r->next = p;            //将结点插入到表头
        r = p;
    }
    r->next = NULL;
}
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号