当前位置: 首页 > 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…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

渲染学进阶内容——模型

最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

C++.OpenGL (10/64)基础光照(Basic Lighting)

基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

html css js网页制作成品——HTML+CSS榴莲商城网页设计(4页)附源码

目录 一、&#x1f468;‍&#x1f393;网站题目 二、✍️网站描述 三、&#x1f4da;网站介绍 四、&#x1f310;网站效果 五、&#x1fa93; 代码实现 &#x1f9f1;HTML 六、&#x1f947; 如何让学习不再盲目 七、&#x1f381;更多干货 一、&#x1f468;‍&#x1f…...

MyBatis中关于缓存的理解

MyBatis缓存 MyBatis系统当中默认定义两级缓存&#xff1a;一级缓存、二级缓存 默认情况下&#xff0c;只有一级缓存开启&#xff08;sqlSession级别的缓存&#xff09;二级缓存需要手动开启配置&#xff0c;需要局域namespace级别的缓存 一级缓存&#xff08;本地缓存&#…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

水泥厂自动化升级利器:Devicenet转Modbus rtu协议转换网关

在水泥厂的生产流程中&#xff0c;工业自动化网关起着至关重要的作用&#xff0c;尤其是JH-DVN-RTU疆鸿智能Devicenet转Modbus rtu协议转换网关&#xff0c;为水泥厂实现高效生产与精准控制提供了有力支持。 水泥厂设备众多&#xff0c;其中不少设备采用Devicenet协议。Devicen…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现指南针功能

指南针功能是许多位置服务应用的基础功能之一。下面我将详细介绍如何在HarmonyOS 5中使用DevEco Studio实现指南针功能。 1. 开发环境准备 确保已安装DevEco Studio 3.1或更高版本确保项目使用的是HarmonyOS 5.0 SDK在项目的module.json5中配置必要的权限 2. 权限配置 在mo…...

Linux-进程间的通信

1、IPC&#xff1a; Inter Process Communication&#xff08;进程间通信&#xff09;&#xff1a; 由于每个进程在操作系统中有独立的地址空间&#xff0c;它们不能像线程那样直接访问彼此的内存&#xff0c;所以必须通过某种方式进行通信。 常见的 IPC 方式包括&#…...