C语言实现无头单链表详解

C语言实现无头单链表详解

什么是无头单链表?

单链表是一种非常常见的数据结构,它由一个个结点组成,每个结点包含两部分:数据部分和next指针部分。数据部分可以存放任何类型的数据,next指针则用于连接下一个结点。

而无头单链表与单链表类似,只是它没有头结点。头结点一般来说用于存放链表的长度、头指针等信息,而无头单链表只有一个指向第一个结点的指针,也就是没有这些额外的信息。

如何实现无头单链表?

下面我们来介绍如何用C语言实现无头单链表。

首先,定义一个结构体来表示单链表的结点:

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

其中,data表示结点中存放的数据,next表示指向下一个结点的指针。

接下来,定义一个指向第一个结点的指针:

Node *head = NULL;

表示空链表。

插入结点

下面是向链表中插入一个新结点的代码:

Node *newNode = (Node*)malloc(sizeof(Node));
newNode->data = data;
newNode->next = head;
head = newNode;

其中,先创建一个新结点newNode,并将其data域赋值为新插入的数据,next域赋值为head。然后将新的头结点指针head指向newNode。

这段代码的作用是将新结点插入到链表的最前面。

删除结点

下面是删除链表中第一个出现的某个元素的代码:

Node *current = head;
Node *previous = NULL;
while (current != NULL && current->data != data) {
    previous = current;
    current = current->next;
}
if (current != NULL) {
    if (previous == NULL) {
        head = current->next;
    } else {
        previous->next = current->next;
    }
    free(current);
}

其中,current表示要删除的结点,previous表示current前面的结点。遍历链表找到要删除的结点后,如果previous为空,表示要删除的是头结点,需要将head指向当前结点的next域。否则,将previous的next指针指向current的next指针,即为删除操作。

示例说明

我们来看一个简单的示例,创建一个空的链表,插入三个结点,然后删除第二个结点:

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

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

int main() {
    Node *head = NULL;
    int data[] = {1, 2, 3};
    int i;

    // 插入结点
    for (i = 0; i < 3; i++) {
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data[i];
        newNode->next = head;
        head = newNode;
    }

    // 遍历链表
    Node *current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    // 删除结点
    Node *previous = NULL;
    current = head;
    while (current != NULL && current->data != 2) {
        previous = current;
        current = current->next;
    }
    if (current != NULL) {
        if (previous == NULL) {
            head = current->next;
        } else {
            previous->next = current->next;
        }
        free(current);
    }

    // 遍历链表
    current = head;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    return 0;
}

输出结果为:

3 2 1 
3 1 

这个示例展示了如何创建一个无头单链表,向链表中插入元素,并删除其中的一项,最后输出结果。

再看一个示例,把链表逆序输出:

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

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

Node *reverse(Node *head) {
    Node *newHead = NULL;
    while (head != NULL) {
        Node *next = head->next;
        head->next = newHead;
        newHead = head;
        head = next;
    }
    return newHead;
}

int main() {
    Node *head = NULL;
    int data[] = {1, 2, 3, 4, 5};
    int i;

    // 插入结点
    for (i = 0; i < 5; i++) {
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->data = data[i];
        newNode->next = head;
        head = newNode;
    }

    // 反转链表
    Node *newHead = reverse(head);

    // 遍历链表
    Node *current = newHead;
    while (current != NULL) {
        printf("%d ", current->data);
        current = current->next;
    }
    printf("\n");

    return 0;
}

这个示例演示了如何把无头单链表逆序输出,在reverse函数中,不断将head指向的结点插入到newHead之前,从而实现链表逆序。

输出结果为:

5 4 3 2 1 

总结

本文介绍了如何用C语言实现无头单链表,包括插入结点、删除结点、遍历链表、逆序输出链表等操作。使用无头单链表时需要注意,它没有头结点,需要特别处理链表是否为空的情况。同时,无头单链表是一种简单而有效的数据结构,用于存储大小不确定的数据,应用广泛。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现无头单链表详解 - Python技术站

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

相关文章

  • 魔兽世界6.0防战天赋属性一览_魔兽世界6.0防战手法攻略心得

    魔兽世界6.0防战手法攻略心得 防战天赋属性一览 作为魔兽世界中的坦克,防战需要具有足够的耐力和护甲来抵挡来自BOSS的攻击,并且通过技能反弹伤害和吸收伤害来保护队友。下面是防战天赋属性的一览: 坦克属性 耐力:提高生命值。 力量:提高攻击和格挡。 敏捷:提高闪避和招架。 智力:提高回蓝和战斗技能的效果。 防御属性 护甲值:抵抗物理伤害。 躲闪值:提高闪避的…

    other 2023年6月27日
    00
  • 反射机制:getDeclaredField和getField的区别说明

    首先需要了解反射机制,它是Java中的一种高级特性,允许程序在运行时获取类的信息以及动态调用它的方法,甚至可以在运行时动态修改类的属性和方法。在反射机制中,我们通常使用Java.lang.reflect包中提供的类完成相关功能。其中,getDeclaredField和getField是两个比较常用的方法,主要用于获取类的字段(属性)信息,它们在使用上也有所区…

    other 2023年6月26日
    00
  • 通过sql语句将blob里的char取出来转成数字保存在其它字段

    要将 blob 字段中的 char 类型数据转换成数字类型并保存在其它字段中,我们可以使用以下步骤: 在数据库表中新建一个列,用于保存转换后的数字。 通过 SQL 语句查询表中 blob 字段的数据,并使用 CAST 函数将其转换成 char 类型。 将 char 类型数据转换成数字,并用 UPDATE 语句将其存入新建的列中。 以下是两条示例说明: 假设我…

    other 2023年6月25日
    00
  • virtualenv安装

    Virtualenv安装攻略 virtualenv是一个用于创建Python虚拟环境的工具,它可以帮助您在同一台机器上管理多个项目,每个项目都有自己的依赖项和Python版本。在本文中,我们将介绍安装virtualenv并创建Python虚拟环境。 步骤1:安装pip 在安装virtualenv之前,您需要先安装pip,它是Python包管理器。在大多数Li…

    other 2023年5月9日
    00
  • react-router-domV6嵌套路由实现详解

    React Router Dom V6 嵌套路由实现详解 React Router Dom 是一个用于在 React 应用中实现路由功能的库。它提供了一组组件,用于管理应用的不同页面和路由之间的导航。 在 React Router Dom V6 中,嵌套路由是一种常见的技术,用于在一个页面中嵌套显示其他页面。这种技术可以帮助我们构建复杂的应用程序布局,并使页…

    other 2023年7月28日
    00
  • 10种excel多条件查找函数的使用方法汇总

    10种Excel多条件查找函数的使用方法汇总 Excel提供了多种函数来进行多条件查找,这些函数可以帮助用户在大量数据中快速定位所需信息。以下是10种常用的Excel多条件查找函数及其使用方法的详细攻略。 1. VLOOKUP函数 VLOOKUP函数用于在垂直数据表中查找某个值,并返回该值所在行的指定列的值。它的基本语法如下: VLOOKUP(lookup_…

    other 2023年7月28日
    00
  • go语言的变量定义示例详解

    Go语言的变量定义示例详解 Go语言是一种静态类型的编程语言,变量定义是其中的基本概念之一。本攻略将详细讲解Go语言中变量的定义方法,并提供两个示例说明。 变量定义方法 在Go语言中,可以使用关键字var来定义变量。变量定义的一般语法如下: var 变量名 类型 其中,变量名是你给变量起的名字,类型是变量的数据类型。 示例一:整数变量 下面是一个示例,展示了…

    other 2023年7月29日
    00
  • css样式优先级及层叠的顺序排序探讨

    CSS样式优先级及层叠的顺序排序探讨 1. 优先级的原则 CSS样式优先级是用来确定当多个样式规则应用于同一个元素时,哪个规则将被应用。在计算优先级时,可以遵循以下原则: !important规则的优先级最高,即使在样式规则中顺序靠后,也会被最先应用。 内联样式(写在HTML元素的style属性中)的优先级高于内部样式表(写在<style>标签中…

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