12.2 单链表
在单链表中,每个结点包含一个指向链表下一节点的指针。链表最后一个节点的指针字段的值为NULL,提示链表后面不再有其他节点。在找到链表的第1个节点后,指针就可以带你访问剩余的所有节点。为了记住链表的起始位置,可以使用一个根指针(root pointer)。根指针指向链表的第1个节点。注意,根指针只是一个指针,它不包含任何数据。
本例中的节点是用下面的声明创建的结构。
typedef struct NODE {
struct NODE *link;
int value;
} Node;
在上图中,这些节点相邻在一起,这是为了显示链表所提供的逻辑顺序。事实上,链表中的节点可能分布于内存中的各个地方。对于一个处理链表的程序而言,各节点在物理上是否相邻并没有什么区别,因为程序始终用链(指针)从一个节点移动到另一个节点。单链表可以通过链从开始位置遍历链表直到结束位置,但链表无法从相反的方向进行遍历。换句话说,当程序到达链表的最后一个节点时,如果想回到其他任何结点,就只能从根指针从头开始。当然,程序移动到下一个节点前可以保存一个指向当前位置的指针,甚至可以保存指向前面几个位置的指针。但是,链表是动态分配的,可能增长到几百或几千个节点,所以要保存所有指向前面位置的节点的指针是不可行的。
在这个程序中,节点根据数据的值按升序链接在一起。对于有些应用程序而言,这种顺序非常重要,比如根据一天的时间安排约会。对于那些不要求排序的应用程序,当然也可以创建无序的链表。
12.2.1 在单链表中插入
怎么才能把一个新节点插入到一个有序的单链表中呢?从概念上说,这个任务非常简单,从链表的起始位置开始,跟随指针直到找到一个大于12的结点,然后把这个新值插入到那个节点之前的位置。
实际的算法则比较有趣。按顺序访问链表,当到达内容为15的节点(第一个值大于12的节点)时就停下来。我们知道这个新值应该添加到这个节点之前,但前一个节点的指针字段必须进行修改以实现这个插入。由于我们已经越过了这个节点,所以无法返回去。解决这个问题的方法就是始终保存一个指向链表当前节点之前的那个节点的指针。
开发一个函数,把一个节点插入到一个有序的单链表中。程序12.1是第一次尝试。
/*
**插入到一个有序的单链表。函数的参数是一个指向链表第一个节点的指针以及需要插入的值。
*/
#include<stdlib.h>
#include<stdio.h>
#include"sll_node.h"
#define FALSE 0
#define TRUE 1
int sll_insert( Node *current, int new_value ){
Node *previous;
Node *new;
/*
**寻找正确的插入位置,方法是按顺序访问链表,直到到达值大于或等于新插入的节点。
*/
while( current->value < new_value ){
previous = current;
current = current->link;
}
/*
**为新节点分配内存,并把新值存储到新节点中,如果内存分配失败,函数返回FALSE。
C和指针 第12章 使用结构和指针 12.2 单链表
于 2022-06-27 09:33:46 首次发布
本文详细介绍了在C语言中如何在有序单链表中插入新节点,包括初始尝试、调试和优化的过程。通过示例代码展示了如何处理插入到链表头部的情况,并强调了消除特殊情况以简化函数的重要性。
摘要由CSDN通过智能技术生成