首页 > 其他分享 >C语言:链表

C语言:链表

时间:2024-11-20 13:43:06浏览次数:3  
标签:Node current head C语言 链表 NULL 节点

链表是一种常见的线性数据结构,其中每个元素(称为节点)包含两部分:数据和指向下一个节点的指针。链表的主要优点是插入和删除操作的时间复杂度较低,但随机访问的效率不如数组。

1. 链表的基本概念

  • 节点(Node):链表的基本单元,包含数据和指向下一个节点的指针。
  • 头节点(Head):链表的第一个节点。
  • 尾节点(Tail):链表的最后一个节点,其指针通常为 NULL。
  • 空链表:没有节点的链表,头节点指针为 NULL。

链表是一种常见的数据结构,它由一系列节点组成。每个节点包含两部分:数据部分和指针部分。数据部分用于存储数据,指针部分用于指向下一个节点,从而将各个节点连接起来。链表可以动态地分配内存,方便地进行插入和删除操作。

2. 链表的操作

常见的链表操作包括:

  • 插入:在链表的某个位置插入一个新节点。
  • 删除:从链表中删除一个节点。
  • 查找:在链表中查找一个节点。
  • 遍历:遍历链表中的所有节点。

3. 实例

下面是一个用C语言实现单向链表的示例:

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

// 定义节点结构
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 创建新节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        printf("Memory allocation failed\n");
        exit(1);
    }
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 在链表头部插入节点
void insertAtHead(Node** head, int data) {
    Node* newNode = createNode(data);
    newNode->next = *head;
    *head = newNode;
}

// 在链表尾部插入节点
void insertAtTail(Node** head, int data) {
    Node* newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode;
    } else {
        Node* current = *head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = newNode;
    }
}

// 删除链表中的节点
void deleteNode(Node** head, int data) {
    if (*head == NULL) {
        printf("List is empty\n");
        return;
    }

    if ((*head)->data == data) {
        Node* temp = *head;
        *head = (*head)->next;
        free(temp);
        return;
    }

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

    if (current->next == NULL) {
        printf("Node with value %d not found\n", data);
        return;
    }

    Node* temp = current->next;
    current->next = current->next->next;
    free(temp);
}

// 查找链表中的节点
Node* search(Node* head, int data) {
    Node* current = head;
    while (current != NULL) {
        if (current->data == data) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 遍历链表并打印所有节点
void printList(Node* head) {
    Node* current = head;
    while (current != NULL) {
        printf("%d -> ", current->data);
        current = current->next;
    }
    printf("NULL\n");
}

// 清空链表
void clearList(Node** head) {
    Node* current = *head;
    while (current != NULL) {
        Node* temp = current;
        current = current->next;
        free(temp);
    }
    *head = NULL;
}

int main() {
    Node* head = NULL;

    insertAtHead(&head, 10);
    insertAtHead(&head, 20);
    insertAtTail(&head, 30);

    printList(head);  // 输出: 20 -> 10 -> 30 -> NULL

    deleteNode(&head, 10);
    printList(head);  // 输出: 20 -> 30 -> NULL

    Node* foundNode = search(head, 30);
    if (foundNode != NULL) {
        printf("Found node with value: %d\n", foundNode->data);
    } else {
        printf("Node not found\n");
    }

    clearList(&head);
    printList(head);  // 输出: NULL

    return 0;
}
  • 代码解释

    • 节点结构 Node:包含一个整数 data 和一个指向下一个节点的指针 next。
    • 创建新节点 createNode:分配内存并初始化节点的数据和指针。
    • 在链表头部插入节点 insertAtHead:创建新节点并将其插入到链表的头部。
    • 在链表尾部插入节点 insertAtTail:创建新节点并将其插入到链表的尾部。
    • 删除链表中的节点 deleteNode:从链表中删除指定值的节点。
    • 查找链表中的节点 search:在链表中查找指定值的节点。
    • 遍历链表并打印所有节点 printList:遍历链表并打印所有节点的数据。
    • 清空链表 clearList:释放链表中所有节点的内存并设置头节点为 NULL。
    • 主函数 main:
      • 创建一个空的链表 head。
      • 插入一些节点并打印链表。
      • 删除一个节点并打印链表。
      • 查找一个节点并输出结果。
      • 清空链表并打印链表。
  • 运行结果:
    在这里插入图片描述

链表的优势在于其动态大小、高效的插入和删除操作、灵活的内存使用。链表适合需要频繁插入和删除元素的场景,尤其是当元素数量不确定时。

标签:Node,current,head,C语言,链表,NULL,节点
From: https://blog.csdn.net/u011732210/article/details/143845377

相关文章

  • 0基础勇闯C语言(2) 数组
    数组可分为数值数组,字符数组,指针数组,结构体数组。一,一维数组1,一维数组的命名inta[5]={1,2,9,23,8};(数组下标范围是0-n-1)2,一维数组的应用冒泡排序和选择排序二,二维数组1,二维数组的命名(2种)inta[2][3]={{1,2,3},{4,5,6}};inta[2][3]={1,2,3,4,5,6};2,二维数组的理解......
  • 动态内存管理(c语言)
    我们通常开辟空间的方式intval=20;//大小为4个字节chararr[10]={0}//开辟出一块连续的空间且大小为10但是上面开辟空间方式的特点1.空间开辟大小是固定的2.数组在声明得时候,必须指定数组得长度,它所需要得内存在编译时分配但是以上的方式不能满足所有情况,有时候......
  • C语言之实现简单的表达式计算器
    C语言之实现简单的表达式计算器这篇博文是对上一篇博文代码的重构!并在此基础上加了一个eval_express函数,实现表达式的交互计算,初步达到REPL,即读表达式、算表达式、输出结果,这样一个循环。定义表达式数据类型和输出函数Express结构体,用来保存表达式的节点数据,运算符或数......
  • 力扣题目解析--合并k个升序链表
    题目给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。示例1:输入:lists=[[1,4,5],[1,3,4],[2,6]]输出:[1,1,2,3,4,4,5,6]解释:链表数组如下:[1->4->5,1->3->4,2->6]将它们合并到一个有序链表中得到。1->1->......
  • c语言if else结构
    c语言if语句如何使用内部是一个判断真假的条件语句,如果该语句为真,就执行其下的一条语句。若有多条语句则应用花括号括起来算作一条语句。一般if和else连用。就是说,满足if条件就执行这个,否则就执行else下的语句。if是c语言的关键字,所有c语言的基本语句都是有编译器(比如VC,GCC......
  • LCR 022. 环形链表 II(中等)(主站142)
    https://leetcode.cn/problems/c32eOV/https://leetcode.cn/problems/linked-list-cycle-ii/难度:☆☆☆题目:给定一个链表,返回链表开始入环的第一个节点。从链表的头节点开始沿着next指针进入环的第一个节点为环的入口节点。如果链表无环,则返回null。为了表示给定......
  • LCR 021. 删除链表的倒数第 N 个结点(中等)(主站19)
    https://leetcode.cn/problems/SLwz0R/https://leetcode.cn/problems/remove-nth-node-from-end-of-list/难度:☆☆☆题目:给你一个链表,删除链表的倒数第n个结点,并且返回链表的头结点。示例:输入:head=[1,2,3,4,5],n=2输出:[1,2,3,5]输入:head=[1],n=1输出......
  • c语言初学者练习——指针进阶学习
    c语言初学者练习——结构体一、字符指针在指针的类型中有一种指针类型为字符指针:char*字符指针的一般使用方法:intmain(){ chara='w'; char*pc=&a; *pc='b'; printf("%c",a); return0;}另一种使用方法:把字符串首字符a的地址赋值给了p,但不安全VS......
  • 【C语言】操作符2(含操作符的应用)
    1、单目操作符    单目操作符有下面几种:    !、++、--、&(取地址)、*(指针)、+(正号)、-(负号)、~、sizeof、(类型)    其中就还有&和*操作符还没有学习过,这个我们在后面学习指针的时候会详细来讲的。2、逗号表达式    逗号表达式就是用逗号隔开的......
  • c语言分支循环语句
    大家好!今天为大家带来的是有关分支与循环语句的相关内容,希望对您有所帮助。正文如下:众所周知,c语言是结构化的程序设计语言,其中的结构化就体现在对于三大基本结构的多元化使用,而这三大结构分别是:顺序结构,选择结构,循环结构通过对三大结构的学习,我们就可以掌握c语言程序的简单......