C语言结构体使用之链表

C语言结构体使用之链表

1. 链表的定义

链表是一种动态数据结构,它由若干个节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。

链表可以分为单链表、双向链表和循环链表几种形式,这里我主要介绍单链表的使用。

2. 链表的声明

链表的声明需要定义链表节点的数据类型,链表的头指针以及一些和链表相关的操作函数。具体代码如下:

//定义链表节点的数据类型
typedef struct node{
    int data;
    struct node *next;
}Node;

//定义链表头指针
typedef struct list{
    Node *head;
    int length;
}List;

//定义链表相关的操作函数
void initList(List *list);
void addNode(List *list, int data);
void deleteNode(List *list, int data);
void printList(List *list);

3. 链表的初始化

链表的初始化需要分配一个头节点,并将头指针指向该节点。链表的长度初始为0。

void initList(List *list){
    Node *head = (Node*)malloc(sizeof(Node));
    head->next = NULL;
    list->head = head;
    list->length = 0;
}

4. 链表的插入

链表的插入可以分为头插法和尾插法两种方式。由于头插法比较简单,这里我只讲解头插法的使用。

void addNode(List *list, int data){
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = list->head->next;
    list->head->next = newNode;
    list->length++;
}

5. 链表的删除

链表的删除可以根据数据元素的值或者节点的位置进行操作,这里我只讲解根据数据元素进行删除的方式。

删除的过程需要找到该节点的前驱节点,将前驱节点的指针指向该节点的后继节点,并释放该节点的内存。

void deleteNode(List *list, int data){
    Node *p = list->head->next;
    Node *pre = list->head;

    while(p != NULL && p->data != data){
        pre = p;
        p = p->next;
    }

    if(p == NULL){
        printf("不存在该节点\n");
    }else{
        pre->next = p->next;
        free(p);
        list->length--;
    }
}

6. 链表的遍历

链表的遍历需要从头节点开始遍历,直到遇到NULL节点截止。在遍历的过程中可以输出节点的数据元素。

void printList(List *list){
    Node *p = list->head->next;

    while(p != NULL){
        printf("%d ", p->data);
        p = p->next;
    }

    printf("\n");
}

7. 链表的使用示例

下面是一个使用链表进行排序的示例程序。

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

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

typedef struct list{
    Node *head;
    int length;
}List;

void initList(List *list);
void addNode(List *list, int data);
void deleteNode(List *list, int data);
void printList(List *list);
void sortList(List *list);

void initList(List *list){
    Node *head = (Node*)malloc(sizeof(Node));
    head->next = NULL;
    list->head = head;
    list->length = 0;
}

void addNode(List *list, int data){
    Node *newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = list->head->next;
    list->head->next = newNode;
    list->length++;
}

void deleteNode(List *list, int data){
    Node *p = list->head->next;
    Node *pre = list->head;

    while(p != NULL && p->data != data){
        pre = p;
        p = p->next;
    }

    if(p == NULL){
        printf("不存在该节点\n");
    }else{
        pre->next = p->next;
        free(p);
        list->length--;
    }
}

void printList(List *list){
    Node *p = list->head->next;

    while(p != NULL){
        printf("%d ", p->data);
        p = p->next;
    }

    printf("\n");
}

void sortList(List *list){
    Node *p = list->head->next;
    int i, j, len = list->length;
    int temp;

    for(i=0; i<len-1; i++){
        p = list->head->next;
        for(j=0; j<len-i-1; j++){
            if(p->data > p->next->data){
                temp = p->data;
                p->data = p->next->data;
                p->next->data = temp;
            }
            p = p->next;
        }
    }
}

int main()
{
    int a[10] = {5, 2, 4, 3, 1, 7, 8, 9, 6, 0};

    List list;
    initList(&list);

    for(int i=0; i<10; i++){
        addNode(&list, a[i]);
    }

    printf("排序前的链表:");
    printList(&list);

    sortList(&list);

    printf("排序后的链表:");
    printList(&list);

    return 0;
}

以上就是关于C语言结构体使用之链表的完整攻略,希望对你有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言结构体使用之链表 - Python技术站

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

相关文章

  • C++双向链表的增删查改操作方法讲解

    关于C++双向链表的增删查改操作方法,一般可以分为以下几步: 第一步:定义链表结构体 我们都知道链表是一种动态数据结构,它的每个元素都包含指向前一个元素和后一个元素的指针。因此,在C++中,我们可以用结构体来定义一个链表节点,具体的定义如下: struct ListNode { int val; ListNode* prev; ListNode* next;…

    other 2023年6月27日
    00
  • 苹果推送(APNs)ios push小结

    苹果推送(APNs)ios push小结 简介 iOS推送通知是一种重要的功能,它可以让App在后台时获得用户的消息提醒,提高用户体验。iOS推送通知的实现依赖苹果推送服务(APNs)。APNs是一种基于HTTP/2协议的推送服务,通过APNs,开发者可以将消息和声音等推送给用户,以供App在后台时获得用户的消息提醒。 基本架构 APNs的基本架构如下: A…

    其他 2023年3月28日
    00
  • Win7系统中启动界面安全模式无法加载disk.sys的解决方法介绍

    Win7系统中启动界面安全模式无法加载disk.sys的解决方法介绍 问题描述 在使用Win7系统时,可能会出现启动界面选择安全模式启动时,出现无法加载disk.sys的错误提示。这会导致系统无法正常启动、进入安全模式或进行系统恢复等操作。 解决方法 针对此问题,可以尝试以下几种方法: 方法一:通过修复和重建BCD文件 使用Win7系统安装盘启动计算机,进入…

    other 2023年6月25日
    00
  • Linux 删除特殊字符文件名或目录的方法

    当我们在Linux系统中使用命令行管理文件和目录时,有时会遇到特殊字符文件名或目录名,如空格、$、*、?等,可能会导致命令行操作出错。本文将介绍如何删除特殊字符的文件名或目录名。 方法一:使用反斜杠转义特殊字符 可以使用反斜杠(\)转义特殊字符,或者使用单引号(’)或双引号(”)将文件名或目录名括起来,防止特殊字符被解释为命令参数。例如删除文件名为“my f…

    other 2023年6月26日
    00
  • Mysql服务器的安装配置与启动关闭方法详解

    Mysql服务器的安装配置与启动关闭方法详解 安装Mysql服务器 步骤一:下载Mysql安装包 官网链接:https://dev.mysql.com/downloads/mysql/ 步骤二:解压安装包 使用以下命令解压安装包: tar -zxvf mysql-xxx.tar.gz -C /usr/local 步骤三:创建Mysql数据存储目录 使用以下命…

    other 2023年6月27日
    00
  • ASP.NET CORE学习教程之自定义异常处理详解

    ASP.NET CORE学习教程之自定义异常处理详解 什么是自定义异常处理 自定义异常处理是指,在应用程序中编写代码,用于处理在程序运行过程中发生的异常情况,比如出现错误、响应超时等情况。在ASP.NET CORE应用程序中,可以使用中间件和过滤器等技术来进行自定义异常处理。 自定义异常处理的好处 使用自定义异常处理有以下好处: 提高应用程序的健壮性和可靠性…

    other 2023年6月25日
    00
  • JVM内存结构相关知识解析

    JVM内存结构相关知识解析 Java虚拟机(JVM)是Java程序的运行环境,它负责将Java字节码转换为机器码并执行。JVM内存结构是指JVM在运行时使用的内存区域,它可以分为以下几个部分: 1. 程序计数器(Program Counter Register) 程序计数器是一块较小的内存区域,它用于存储当前线程正在执行的字节码指令的地址。每个线程都有自己独…

    other 2023年8月1日
    00
  • Android中ImageView实现选择本地图片并显示功能

    当在Android中使用ImageView实现选择本地图片并显示功能时,可以按照以下步骤进行操作: 添加权限:首先,在AndroidManifest.xml文件中添加读取外部存储器权限。在<manifest>标签内添加以下代码: <uses-permission android:name=\"android.permission.…

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