C语言数据结构之单链表存储详解

C语言数据结构之单链表存储详解

什么是单链表

链表是一种非顺序存储的数据结构,其每个节点都保存下一个节点的地址。单链表是最简单的链表,每个节点只包含下一个节点的地址。

单链表节点的定义

单链表的节点定义一般包括两个部分:数据域和指针域。数据域存放节点的数据,指针域存放下一个节点的地址。

以下是单链表节点的定义:

typedef struct node {
    int data;           // 数据域
    struct node *next;  // 指针域
} Node, *LinkList;

这里使用typedefLinkList是为了方便使用。详情可以参考代码。

单链表的基本操作

头插法创建单链表

头插法是一种从前往后建立单链表的方法,每次新建节点都插入到链表的头部。

LinkList createList() {
    LinkList L = NULL;      // 头节点
    Node *s = NULL;         // 新建节点
    int x = 0;              // 输入的数据
    scanf("%d", &x);
    while (x != -1) {
        s = (Node*)malloc(sizeof(Node));    // 新建节点
        s->data = x;        // 节点赋值
        s->next = L;        // 插入到链表头部
        L = s;              // 更新头指针为新建节点
        scanf("%d", &x);
    }
    return L;
}

以上代码是使用头插法创建单链表的实现。程序首先输入第一个数据,然后循环输入数据并新建节点,每次将新节点插入到头部。这里需要注意的是如果有一个数据为-1,那么循环结束,返回头节点。

尾插法创建单链表

尾插法是一种从后往前建立单链表的方法,每次新建节点都插入到链表的尾部。

LinkList createList() {
    LinkList L = NULL;      // 头节点
    Node *s = NULL;         // 新建节点
    Node *r = NULL;         // 指向链表的尾部
    int x = 0;              // 输入的数据
    scanf("%d", &x);
    while (x != -1) {
        s = (Node*)malloc(sizeof(Node));    // 新建节点
        s->data = x;        // 节点赋值
        if (L == NULL) {    // 链表为空,新节点就是链表的头节点
            L = s;
            r = s;
        } else {            // 新节点插入到链表的尾部
            r->next = s;
            r = s;
        }
        scanf("%d", &x);
    }
    if (r != NULL) {    // 这里需要判断一下,以免链表为空
        r->next = NULL;
    }
    return L;
}

以上代码是使用尾插法创建单链表的实现。程序首先输入第一个数据,然后循环输入数据并新建节点,每次将新节点插入到尾部。这里需要注意的是如果有一个数据为-1,那么循环结束。最后需要判断一下链表是否为空,如果不为空则设置尾部指针为空指针。

遍历单链表

遍历单链表就是依次输出每个节点的数据。

void printList(LinkList L) {
    Node *p = NULL;     // 遍历指针
    p = L;
    while (p != NULL) {
        printf("%d ", p->data);
        p = p->next;
    }
    printf("\n");
}

以上代码是遍历单链表的实现。程序创建了一个指针p用于遍历单链表,当p指向空指针时遍历结束。

单链表的应用举例

静态链表

静态链表是一种使用数组来模拟的链表。静态链表的一个显著特点是可以随机访问节点。

以下是静态链表节点定义:

typedef struct snode {
    int data;
    int next;
} SNode;

静态链表的代码实现和单链表基本相同,只是在创建节点的时候需要使用数组下标代替地址。

void createSList(SNode s[], int *p) {
    int x = 0;              // 输入数据
    scanf("%d", &x);
    while (x != -1) {
        s[*p].data = x;
        s[*p].next = *p + 1;
        *p++;
        scanf("%d", &x);
    }
    s[*p].next = -1;
}

void printSList(SNode s[], int p) {
    while (s[p].next != -1) {
        printf("%d ", s[p].data);
        p = s[p].next;
    }
    printf("%d\n", s[p].data);
}

以上代码实现了静态链表的创建和遍历。程序使用数组来保存静态链表,p代表数组下标,每次新增节点的地址都是p+1。静态链表的遍历需要使用数组下标代替指针指向节点位置。

单链表的逆序输出

单链表的逆序输出不需要改变节点的位置,只需要修改遍历顺序。这可以通过使用递归函数来实现。

void reversePrint(Node *L) {
    if (L == NULL) {
        return;
    }
    reversePrint(L->next);
    printf("%d ", L->data);
}

以上代码实现了单链表逆序输出的功能。reversePrint函数使用递归的形式来遍历链表,当遇到空指针时递归结束。同时,printf函数在递归函数后面执行,所以输出顺序就是逆序的了。

结论

以上是C语言单链表存储的详细攻略。单链表是一种比较简单的数据结构,可以用来解决许多实际问题。在实际应用中,我们需要灵活使用各种算法和技巧来处理单链表。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言数据结构之单链表存储详解 - Python技术站

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

相关文章

  • 数据结构 双向链表的创建和读取详解及实例代码

    下面我为你详细讲解“数据结构 双向链表的创建和读取详解及实例代码”的完整攻略。 什么是双向链表? 双向链表是一种常见的线性数据结构,与单向链表相比,它可以在节点之间建立双向连接,使得在需要反向遍历链表时效率更高。每个节点同时保存了指向前一个节点和后一个节点的指针,因此双向链表也叫做双链表。 双向链表的创建 定义节点类 首先,我们需要定义一个表示节点的类,该类…

    数据结构 2023年5月16日
    00
  • Go 数据结构之堆排序示例详解

    Go 数据结构之堆排序示例详解 什么是堆? 堆(Heap)是一种特殊的树形数据结构,它满足下列性质: 堆中每个节点的关键字都不大于(或不小于)其子节点的关键字。 堆中,根节点(顶端)是最小或最大元素。 堆实际上是一个完全二叉树,因此可以用数组实现。对于下标为i的节点,其左子节点为2i,右子节点为2i+1,父节点为i/2。 堆分为最大堆和最小堆。在最大堆中,父…

    数据结构 2023年5月17日
    00
  • C语言树状数组的实例详解

    首先需要了解什么是树状数组。树状数组(Binary Indexed Tree,BIT),也叫做 Fenwick 树(树状数组的发明者是Peter M. Fenwick),是一个查询和修改复杂度都为 log(n) 的数据结构,与线段树类似,但使用起来比线段树更加方便以及简洁。 在该攻略中,我们将通过两条树状数组的实例,详细讲解树状数组,让读者更好地理解树状数组…

    数据结构 2023年5月17日
    00
  • PHP 数据结构 算法 三元组 Triplet

    PHP 数据结构 算法 三元组 Triplet 什么是三元组 Triplet 三元组 Triplet 是指由三个数据分别确定一个元素的数据类型。 在 PHP 中可以用一个数组来实现三元组,数组下标表示元素的序号,数组中储存的则是元素的值,共有三个元素。 例如一个三元组 (a, b, c),可以用 PHP 数组表示为 $triplet = array(a, b…

    数据结构 2023年5月17日
    00
  • nginx内存池源码解析

    Nginx内存池源码解析 Nginx是一个高性能、高并发的Web服务器。为了提高其性能和速度,Nginx采用了特殊的内存管理机制,即内存池。 什么是内存池? 内存池是一种高效的内存分配和管理机制。它将一块内存划分成多个大小相等的块,并按需分配给系统。当内存块不再使用时,它并不被立即释放,而是留在内存池中待重复利用。 Nginx内存池结构 Nginx内存池主要…

    数据结构 2023年5月17日
    00
  • C++数据结构之二叉搜索树的实现详解

    C++数据结构之二叉搜索树的实现详解 1. 什么是二叉搜索树? 二叉搜索树是一种二叉树,其中每个节点都包含一个键值,且每个节点的键值都大于其左子树中任何节点的键值,小于其右子树中任何节点的键值。如下图所示: 9 / \ 4 15 / \ 12 20 在上面的二叉搜索树中,节点的键值分别是9, 4, 15, 12, 20,且每个节点的键值都符合上述定义。 2.…

    数据结构 2023年5月17日
    00
  • C语言全面讲解顺序表使用操作

    C语言全面讲解顺序表使用操作 什么是顺序表 顺序表(Sequential List)是一种常见的数据结构,它由一组连续的存储单元组成,并且支持随机访问。通常我们使用数组来实现顺序表。 顺序表的基本操作 初始化 在使用顺序表之前,需要先进行初始化。顺序表的初始化包括两个步骤:指定顺序表的大小,申请内存空间。具体代码如下: #define MAXSIZE 100…

    数据结构 2023年5月17日
    00
  • Java数据结构之顺序表篇

    Java数据结构之顺序表篇 什么是顺序表 顺序表是由一组地址连续、大小相等的存储单元依次存储数据元素的线性表。 顺序表的表示 Java语言中,可以使用数组来表示顺序表。 public class SeqList<T> { private Object[] element;// 定义数组存储数据元素 private int length;// 当前…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部