当前位置: 首页 > news >正文

C语言复习-链表

链表:


特点:

通过 next 指针 把内存上不连续 的几段数据 联系起来

set nu -- 打印行号

概念: 一种数据结构 -- 数据存放的思想

比如 -- 数组 -- 内存连续的一段空间,存放相同类型的一堆数据
缺点 -- 增删元素很 难  -- 不灵活 --> 引入链表

 next指针的初步认识:


#include<stdio.h>

struct chain
{
int num;
struct chain* next;
};


int main()
{
int arr[3]={1,2,3};
puts("use arr to output:");

for(int i=0;i<3;++i)
{
printf("%d ",arr[i]);
}
puts("");
struct chain a={1,NULL};
struct chain b={2,NULL};
struct chain c={3,NULL};

a.next=&b;
b.next=&c;
puts("use chain to output:");
printf("%d %d %d\n",a.num,a.next->num,b.next->num);

return 0;
}


遍历:


遍历条件 -- 尾部元素的next 指针为NULL -- 结束条件

遍历 只需要 传入首元素的地址就-ok -> 后续元素直接 next去获取


#include<stdio.h>

struct chain
{
int num;
struct chain* next;
};


void printChain(struct chain* head)
{
struct chain* p=head;
while(p!=NULL)
 {
 printf("%d ",p->num);
 p=p->next;
 }

puts("");
}


int main()
{
int arr[3]={1,2,3};
puts("use arr to output:");

for(int i=0;i<3;++i)
{
printf("%d ",arr[i]);
}
puts("");
struct chain a={1,NULL};
struct chain b={2,NULL};
struct chain c={3,NULL};

a.next=&b;
b.next=&c;
puts("use chain to output:");
//printf("%d %d %d\n",a.num,a.next->num,b.next->num);

printChain(&a);


return 0;
}

//p-> next 下一个元素的地址


==========================================

列表的查找

int getTotal(struct chain* head) //获得链表长度
{
int cnt=0;
while(head!=NULL)
{
cnt++;
head=head->next;
}
return  cnt;
}

int  check(struct chain* head,int n) //查看n是否在链表内
{
while(head!=NULL)
{
if(head->num==n) return 1;

head=head->next;
return 0;
}

=================================


插入新节点

后面插入


int  insert(struct chain* head,int data,struct chain*new)
{
    struct chain* p=head;
    while(p!=NULL)
    {
     if(p->num==data) //找到目标元素位置
      {
        new->next=p->next; //插入到目标元素后面
        p->next=new; //目标元素的下一个数改为插入值

        return 1;
      }

    p=p->next;
    }
    return  0;

}

==============================================

前面插入

struct chain* frontInsert(struct chain* head,int data,struct chain*new)
{
struct chain* p=head;
if(p->num==data) //在头部插入
{
new->next=head;//换头
puts("insert succeed");
return new;
}

while(p->next!=NULL)
{
if(p->next->num==data) // 找到目标元素的上一个元素位置
 {
  
new->next=p->next; //差到目标元素上一个元素的后面就是目标元素的前面
p->next=new; //目标元素的上一个元素指向我们的插入值

puts("insert succeed");
return head;
 }
p=p->next;

}
puts("insert failed!!");
return head;

}

==================================


删除指定节点:

分情况:
1.改头  -- 记得把之前的头free掉(malloc 创建的才能free -- 一般也是malloc去创建),避免浪费系统空间
2.跳过

struct chain* myRemove(struct chain* head,int data)
{
struct  chain *p =head;

if(p->num==data) //第一个就是目标
{
    head=head->next;
    return head;
}

while(p->next!=NULL)
{
 if(p->next->num==data)
 {
 p->next=p->next->next; //跳过中间值 == 删除

//注-- if 是malloc 动态创建的内存空间这里要free释放掉--一般都是动态内存空间
return head;
 } 
p=p->next;
}
return head;


}


================================================

链表的动态创建: 

头插法


struct chain* frontCreate(struct chain* head)
{
struct chain*new=NULL;


while(1)
{
new=(struct chain*)malloc(sizeof(struct chain)); //拿到一块新的内存空间
puts("清输入一个数字, 0--退出!");
scanf("%d",&new->num);

 if(new->num==0)
  {
  puts("0 -- quit");
  return head;
  }

 if(head==NULL)
  {
  head=new; //给链表头赋值
  }
  else
  {
    new->next=head; //头插,新元素插到头后面
    head=new; //然后新的节点变成头  -- 类似栈 --先进后出

  }
  
}

return  head;

}

========================================

优化-- 循环 和 头插 分开写

struct chain *frontCreate(struct chain *head, struct chain *new)
{

    if (head == NULL)
    {
        head = new;
    }
    else
    {
        new->next = head;
        head = new;
    }

    return head;
}

struct chain *myCreate(struct chain *head)
{
    while (1)
    {
        struct chain *new = NULL;

        new = (struct chain *)malloc(sizeof(struct chain));
        puts("清输入一个数字, 0--退出!");
        scanf("%d", &new->num);

        if (new->num == 0)
        {
            puts("0 -- quit");
            free(new);
            return head;
        }
       head= frontCreate(head, new);
    }
    return head;
}


========================================


尾插法


struct chain *behindCreate(struct chain *head, struct chain *new)
{
    struct chain *p = head;
    if (head == NULL)
    {
        head = new;
        return head;
    }
    while (p->next != NULL) //拿到尾部位置 p==NULL
    {
        p = p->next;
    }
    p->next = new; //直接在当前链表的尾部添加

    return head;
}


===================================


整个程序:


#include <stdio.h>

struct chain
{
    int num;
    struct chain *next;
};

void printChain(struct chain *head)
{
    struct chain *p = head;
    while (p != NULL)
    {
        printf("%d ", p->num);
        p = p->next;
    }

    puts("");
}

int getTotal(struct chain *head)
{
    int cnt = 0;
    while (head != NULL)
    {
        cnt++;
        head = head->next;
    }
    return cnt;
}

int check(struct chain *head, int n)
{
    while (head != NULL)
    {
        if (head->num == n)
            return 1;

        head = head->next;
        return 0;
    }
}

void modif(struct chain *head, int n, int new)
{
    struct chain *p = head;
    while (p != NULL)
    {
        if (p->num == n)
        {
            p->num = new;
            puts("修改成功!");
        }

        p = p->next;
    }
}

int insert(struct chain *head, int data, struct chain *new)
{
    struct chain *p = head;
    while (p != NULL)
    {
        if (p->num == data)
        {
            new->next = p->next;
            p->next = new;
            return 1;
        }

        p = p->next;
    }
    return 0;
}

struct chain *frontInsert(struct chain *head, int data, struct chain *new)
{
    struct chain *p = head;
    if (p->num == data) // 在头部插入
    {
        new->next = head; // 换头
        puts("insert succeed");
        return new;
    }

    while (p->next != NULL)
    {
        if (p->next->num == data)
        {

            new->next = p->next;
            p->next = new;
            puts("insert succeed");
            return head;
        }
        p = p->next;
    }
    puts("insert failed!!");
    return head;
}

struct chain *myRemove(struct chain *head, int data)
{
    struct chain *p = head;

    if (p->num == data) // 第一个就是目标
    {
        head = head->next;
        return head;
    }

    while (p->next != NULL)
    {
        if (p->next->num == data)
        {
            p->next = p->next->next;
            return head;
        }
        p = p->next;
    }
    return head;
}

struct chain *frontCreate(struct chain *head, struct chain *new)
{

    if (head == NULL)
    {
        head = new;
    }
    else
    {
        new->next = head;
        head = new;
    }

    return head;
}

struct chain *behindCreate(struct chain *head, struct chain *new)
{
    struct chain *p = head;
    if (head == NULL)
    {
        head = new;
        return head;
    }
    while (p->next != NULL)
    {
        p = p->next;
    }
    p->next = new;

    return head;
}

struct chain *myCreate(struct chain *head,int func)
{
    while (1)
    {
        struct chain *new = NULL;

        new = (struct chain *)malloc(sizeof(struct chain));
        puts("清输入一个数字, 0--退出!");
        scanf("%d", &new->num);

        if (new->num == 0)
        {
            puts("0 -- quit");
            free(new);
            return head;
        }
        if(func)
        head = frontCreate(head, new);
        else
        head = behindCreate(head, new);
    }
    return head;
}

int main()
{

    puts("use chain to output:");
    // printf("%d %d %d\n",a.num,a.next->num,b.next->num);
    struct chain *head = NULL;
    int func;
    puts("清选择插入方式:1--头插  0--尾插");
    scanf("%d",&func);
    head = myCreate(head,func);

    printChain(head);

    // insert(&a,1,&new);
    // head=frontInsert(head,4,&new);
    // head=myRemove(head,4);
    // modif(head,4,255);
    // printChain(head);

    return 0;
}

相关文章:

C语言复习-链表

链表: 特点: 通过 next 指针 把内存上不连续 的几段数据 联系起来 set nu -- 打印行号 概念: 一种数据结构 -- 数据存放的思想 比如 -- 数组 -- 内存连续的一段空间&#xff0c;存放相同类型的一堆数据 缺点 -- 增删元素很 难 -- 不灵活 --> 引入链表 next指针的初步认识…...

Redis面试题-缓存雪崩、缓存穿透、缓存击穿问题

1 穿透: 两边都不存在&#xff08;皇帝的新装&#xff09; &#xff08;黑名单&#xff09; &#xff08;布隆过滤器&#xff09; 2 击穿&#xff1a;一个热点的key失效了&#xff0c;这时大量的并发请求直接到达数据库. &#xff08;提前预热&#xff09; 3 雪崩&#xff1a…...

【Node.js】npx

概述 npx 可以使用户在不安装全局包的情况下&#xff0c;运行已安装在本地项目中的包或者远程仓库中的包。 高版本npm会自带npx命令。 它可以直接运行 node_modules/.bin 下的 exe 可执行文件。而不像之前&#xff0c;我们需要在 scripts 里面配置&#xff0c;然后 npm run …...

hive授予指定用户特定权限及beeline使用

背景&#xff1a;因业务需要&#xff0c;需要使用beeline对hive数据进行查询&#xff0c;但是又不希望该用户可以查询所有的数据&#xff0c;希望有一个新用户bb给他指定的库表权限。 解决方案&#xff1a; 1.赋权语句&#xff0c;使用hive管理员用户在终端输入hive进入命令控…...

Vmware虚拟机无法用root直连说明

Vmware虚拟机无法用root直连说明 背景目的SSH服务介绍无法连接检查配置 背景 今天在VM上新装了一套Centos-stream-9系统&#xff0c;网络适配器的连接方式采用的是桥接&#xff0c;安装好虚拟机后&#xff0c;在本地用ssh工具进行远程连接&#xff0c;ip、用户、密码均是成功的…...

Visio中存在问题的解决方法

公式缩放 mathtype公式在visio缩放之后&#xff0c;出现了变形。 解决方法&#xff1a;每次输入公式都通过 插入->对象->mathType Equation 新建一个公式。可以避免 注&#xff1a;网上有的说在word中使用mathtype编写公式&#xff0c;之后复制到visio中。 插入波形 选择…...

taro之Swiper的使用

图样&#xff1a; 往往我们需要轮播图去显示我们想要的图片之类的 这是工作的代码 <View classNametop-title><SwiperclassNamebanner-swiperinterval{3000}circularautoplay>{homeBannerList.map((item) > {return (<SwiperItem key{item.id}><View…...

正大国际:金融行业发展趋势

2024金融科技趋势研究报告 大模型生态揭秘!金融行业迎来变革&#xff0c;中控成生态核心&#xff0c;大模型在金融行业的应用 随着大模型的不断发展&#xff0c;越来越多的金融机构开始尝试在一些业务场景中引入大模型和生成式A能力&#xff0c;预计2024年&#xff0c;领先的金…...

vue中实现超出一行 展开和收起的功能

html中: <divclass="txttype"ref="txttype"style="margin-bottom: 6px":class="hidetext == true ? hidetext : "><div style="width: 96%"><el-tagtype="info"style="margin-right: 10px&…...

记录一次使用cert-manager-颁发CA证书

一、官网 SelfSigned - cert-manager Documentation 二、例子 apiVersion: v1 kind: Namespace metadata:name: sandbox --- apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata:name: selfsigned-issuer spec:selfSigned: {} --- apiVersion: cert-manager.io/v…...

生成式AI的风险与挑战

生成式AI&#xff0c;即通过训练数据生成新的文本、图像或音频等内容的人工智能技术&#xff0c;具有很多潜在的风险与挑战。 1. 信息可信度&#xff1a;生成式AI往往是基于大量训练数据&#xff0c;但这些数据可能存在偏见、错误或虚假信息。生成的内容可能会引入不准确或误导…...

让IIS支持.NET Web Api PUT和DELETE请求

前言 有很长一段时间没有使用过IIS来托管应用了&#xff0c;今天用IIS来托管一个比较老的.NET Fx4.6的项目。发布到线上后居然一直调用不同本地却一直是正常的&#xff0c;关键是POST和GET请求都是正常的&#xff0c;只有PUT和DELETE请求是有问题的。经过一番思考忽然想起来了I…...

运维小技能:IP多号段配置、重置Mac电脑密码、修改系统级别的文件

文章目录 I 清除last_run_metadata_path数据。1.1 删除文件1.2 清空一个目录下所有文件的内容1.3 定期重启Logstash,并清除last_run_metadata_path数据。II 配置IP2.1 CentOS系统的IP参数2.2 shell脚本-静态网络配置III 电脑的IP多号段配置3.1 Mac电脑3.2 windows系统IV mac Ro…...

Docker的Ubuntu上的安装教程及相关命令

一、简介 Docker 是一个开源的应用容器引擎&#xff0c;可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&#xff0c;这个容器是完全使用沙箱机制&#xff08;限制容器内部对系统资源的访问&#xff09;&#xff0c;更重要的是容器性能开销极低。 正是因为…...

一些常见的nacos问题和答案

什么是Nacos&#xff1f;它的作用是什么&#xff1f; Nacos是一个动态服务发现、配置管理和服务管理平台。它的作用是帮助应用程序实现服务注册与发现、动态配置管理和服务健康管理等功能。 Nacos的核心功能包括哪些&#xff1a; 服务注册与发现&#xff1a;Nacos支持基于DN…...

华为OD机22道试题

华为OD机试题 2.查找小朋友的好朋友位置 在学校中&#xff0c;N 个小朋友站成一队&#xff0c;第 i 个小朋友的身高为 height[i]&#xff0c;第 i 个小朋友可以看到第一个比自己身高更高的小朋友j&#xff0c;那么 j 是 i 的好朋友 (要求&#xff1a;j>i) 。 请重新生成一个…...

什么是Prompt Tuning?

本文是观看视频What is Prompt Tuning?后的笔记。 大语言模型&#xff08;如ChatGPT &#xff09;是基础模型&#xff0c;是经过互联网上大量知识训练的大型可重用模型。 他们非常灵活&#xff0c;同样的模型可以分析法律文书或撰写文章。 但是&#xff0c;如果我们需要用其解…...

正则表达式篇

文章目录 1. 导入re模块2. 正则表达式的基本模式3. re模块的主要函数和方法4. 示例 正则表达式&#xff08;Regular Expression&#xff0c;常简写为regex或regexp&#xff09;是一种强大的文本处理工具&#xff0c;它使用一种特殊的字符序列来帮助用户检查一个字符串是否与某种…...

CAST(columnA AS VARCHAR(255)) AS fieldA报错的问题

列类型转换&#xff0c;不能使用VARCHAR&#xff0c;是能使用CHAR 应该改为&#xff1a; CAST(columnA AS CHAR(255)) AS fieldA报错的问题...

github加速神器!解决github巨慢的问题,并且能够加速下载!另外推荐GitKraken -- 超好用的 Git 可视化工具

FastGithub github加速神器&#xff0c;解决github打不开、用户头像无法加载、releases无法上传下载、git-clone、git-pull、git-push失败等问题。 下载地址&#xff1a; 清华云盘 2 部署方式 2.1 windows-x64桌面 双击运行FastGithub.UI.exe 2.2 windows-x64服务 fastgi…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...