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

C语言:链表

时间:2024-09-15 21:24:39浏览次数:3  
标签:结点 NULL struct next 链表 C语言 ST

链表是一种常见的基础数据结构,它由一系列节点(Node)组成。每个节点包含两部分:数据域(存储数据)和指针域(存储下一个节点的地址)。链表的特点是元素在内存中不一定连续存储,而是通过指针连接起来。

以下是链表的一些基本特点:

  1. 动态性:链表的长度可以动态变化,不需要在创建时指定大小。
  2. 灵活性:链表可以方便地插入和删除元素,不需要像数组那样进行大量元素的移动。
  3. 多样性:链表有多种形式,如单向链表、双向链表、循环链表等。

以下是链表的主要类型:

  1. 单向链表:每个节点只有一个指针,指向下一个节点。
  2. 双向链表:每个节点有两个指针,一个指向前一个节点,另一个指向下一个节点。
  3. 循环链表:链表中最后一个节点的指针指向第一个节点,形成一个环。

1. 链表操作简介

在操作链表之前,要先来设计链表中每个结点的数据结构。我们设计一个学生的结构体变量,用来存放学生的学号和分数。

struct ST{
    int n;
    int score;
    struct ST *next;
};

在 C 语言中,指针必须指定它所指向的数据类型。由于 next 需要指向链表中的下一个 struct ST 类型的节点,因此它的类型必须是 struct ST *

另外,为了处理方便,通常都是在线性单向链表的第一个结点之前额外增加一个结点,称之为“头结点”。 

2. 空链表的建立

这里所说的空链表,是指只含有一个头结点的链表。

struct ST *createNullList()
{
    struct ST* head;
    head=(struct ST*)malloc(sizeof(struct ST));
    if(head!=NULL)
        head->next=NULL;
    else
        printf("Out of space!\n");
    return head;
}

动态内存分配有可能失败,因此需要检查head中 所存的值是否为NULL。若为NULL,表示空间分配失败,若不为NULL,则表示头结点已经成功分配。由于空链表没有实际结点,因此头结点的指针域应该存为NULL。 

3. 判断链表是否为空

int isNullList(struct ST* head)    //传进去头指针
{
    return head->next==Null;    //判断语句
}

4. 在链表最后添加一个结点

int append(struct ST* head, int n, int s)
{
    struct ST* p,*pnew;
    pnew = (struct ST*)malloc(sizeof(struct ST));
    if(pnew==NULL){
        printf("Out of space!");
        return 0;
    }
    else{
        pnew->n=n;
        pnew->sorce=s;
        p=head;                //p先指向头结点
        while(p->next!=NULL)   //若p所指不是链尾
            p=p->next;         //p后移一个结点
        p->next=pnew;          //链尾的next存储新结点指针
        pnew->next=NULL;       //使新结点成为链尾
    }
    return 1;
}

5. 求某结点的指针

例如,要查找链表中学号为n的结点的指针。

查找要从链表的第一个结点开始,依次将每个结点的学号与n比较,若找到该同学,返回其地址,若找不到,则返回NULL。

struct ST* locate(struct ST* head, int n)
{
    struct ST* p;
    p=head->next;            //将头结点的next域赋值给P,使指向第一个结点
    while(p!=NULL&&p->n!=n)  //如果p存的不是NULL(表示P指向一个实际存在的结点)
        p=p->next;
    return p;
}

6. 求p所指结点的前驱(前一个结点)

struct ST* locatePre(struct ST* head, struct ST* p)
{
    struct ST* ptemp;
    ptem=head;
    while(ptemp!=NULL&&ptemp->next!=p)
        ptemp=ptemp->next;
    return ptemp;
}

判断ptemp是不是等于NULL以及ptemp->next是不是等于p;

若两者都不是,则执行ptemp=ptemp->next,重复上一个步骤;

若ptemp等于NULL,表示已经找遍所有结点但没有找到p所指的结点,退出循环,返回NULL。若ptemp->next=p,则ptemp所指结点就是p所指结点的前驱,退出循环,返回ptemp。

7. 在某结点之后插入一个新结点

 

 

int insert(struct ST* head, struct ST* p, int n, float score)
{
    struct ST* pnew=(struct ST*)malloc(sizeof(struct ST));
    if(pnew==NULL){
        printf("Out of space!\n");
        return 0;
    }
    pnew->num=n;
    pnew->score=score;
    pnew->next=p->next;
    p->next=pnew;
    return 1;
}

8. 结点的删除

 

 

int delete(struct ST* head, int n)
{
    struct ST *p1,*p2;
    p1=head;
    //下面用循环来查找学号为n的结点的前驱
    while(p1->next!=NULL&&p1->next!=n)
        p1=p1->next;
    if(p1->next==NULL){
        printf("Not exist!\n");
        return 0;
    }
    p2=p1->next;
    p1->next=p2->next;
    free(p2);
    return 1;
}

 

 

标签:结点,NULL,struct,next,链表,C语言,ST
From: https://blog.csdn.net/2302_80978287/article/details/142267259

相关文章

  • C语言:结构体
    一、结构体的概念和定义1.为什么要定义结构体结构体是由用户自己定义(设计)的数据类型。其实就是各种信息的打包。比如说,每个学生都有学号、姓名和成绩,100个学生就有100份这种数据,打包起来整合就会方便很多。2.结构体定义的格式struct[结构体名]{    成员列表}......
  • C语言一些简单的细节记录
    一、声明和定义的区别1.声明(Declaration):是告诉编译器有一个变量、函数或类型存在,但不为其分配内存或提供具体的实现。声明提供了有关标识符(如变量名、函数名)的信息,包括类型和名称。它们通常在头文件中出现,以便在多个源文件中共享。例如,以下是变量、函数和类型的声明示例:......
  • c语言写的环形队列
            以下是一个简单的环形队列的实现示例,包括初始化、入队、出队、查询当前元素个数、队列长度和队列元素可视化。        这里使用了静态数组来实现队列的存储,适合于固定大小的队列。#include<stdio.h>#defineMAX_QUEUE_SIZE10 //定义队列的最大......
  • 带你深入了解C语言指针(三)
    目录前言一、字符指针变量字符数组与常量字符串二、数组指针变量1.数组指针变量是什么2.数组指针变量怎么初始化3.数组指针怎么利用?三、二维数组传参四、函数指针变量1.函数指针变量的创建2.函数指针变量的使用3.typedef4.define和typedef的区别五、函数指针数......
  • 条件编译 - 代码裁剪的工具 --进阶C语言
    目录条件编译-代码裁剪的工具为何要有条件编译条件编译都在那些地方用?见一见条件编译的代码宏是否被定义vs宏是否为真or假编译器也能够自动帮你加上宏GCCVS2023-VS2019#ifdef/#ifndef#if注意事项让#if和#ifdef/#ifndef完全一样条件编译也支持嵌套一个使用#ifdefined能起到很......
  • Day4||24.两两交换链表中的节点|19.删除链表的倒数第n个结点|面试题:链表相交|142.环形
    24.两两交换链表中的节点题目:24.两两交换链表中的节点-力扣(LeetCode)给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。图解思路首先,虚拟头结点挺方便链表进行增删改操作的。本题操作用到三......
  • 循环语句与条件语句的细节与思想 --进阶C语言
    目录if-else组合if的执行顺序操作符的执行顺序测试方法C语言的布尔类型switchcase组合(补充)屏蔽警告的方法在case中执行多条语句,建议case后都带上花括号.多个case执行同样语句do、while、for循环的基本结构continue跳转的位置循环设计的思想推荐推荐使用for的前闭后开写法null......
  • 链表的快速排序(C/C++实现)
    一、前言大家在做需要排名的项目的时候,需要把各种数据从高到低排序。如果用的快速排序的话,处理数组是十分简单的。因为数组的存储空间的连续的,可以通过下标就可以简单的实现。但如果是链表的话,内存地址是随机分配的,不能像数组那样通过下标就直接实现。所以在这里给大家介绍......
  • 鹏哥C语言36-37---循环/分支语句练习(折半查找算法)
    #define_CRT_SECURE_NO_WARNINGS//----------------------------------------------------------------------------------------------------3.4分支,循环练习//用代码解决问题=先想办法(编程思维)+再写代码(按照语法形式)//--------------------------------------------......
  • 鹏哥C语言34---循环语句 do while
    //-------------------------------------------------------------------------------------------------3.3dowhile循环#include<stdio.h>//---------------------------------------------------------------------------------------------3.3.1do语句的语法/*do......