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

C#单向链表实现:Append,Move,Delete,InsertAscending, InsertUnAscending,Clear

目录

一、链表定义

二、链表设计 

1.先定义一个结点类(Node)

2.再定义链表类(LinkedList)并依次设计其方法

3.再实现删除方法

4.再实现Insert 的方法

5.再增加InsertAscending升序插入

6.再增加 InsertUnAscending 的方法

7.再增加一个Clear方法,清空链表

8.再增加GetCurrentValue()方法取得当前的值

三、设计一个Main方法演示上述方法的应用


一、链表定义

        链表是一种特殊的数据结构,能够动态地存储一种结构类型数据。在开发复杂的系统时,经常会使用链表存储数据。

        链表是一种重要的数据结构,该结构由节点组成。每个节点包含两部分数据,第一部分是节点本身的数据,第二部分是指向下一个节点的指针。对于单向链表,链表中存在两个特殊的节点,分别为“头节点”和“尾节点”。头节点本身没有数据,只存储下一个节点的指针,尾节点只存储数据。

二、链表设计 

1.先定义一个结点类(Node)

public class Node
{public object Data { get; set; }public Node Next { get; set; }public Node Previous { get; set; }public Node(object data){Data = data;Next = null;Previous = null;}
}

2.再定义链表类(LinkedList)并依次设计其方法

        链表类中使用了三个指针:Head、Tail和Current。Head指针指向链表的头部,Tail指针指向链表的尾部,Current指针指向当前正在访问的结点。

        定义了以下方法来实现结点的移动和添加:

  • Append:在链表的尾部添加一个新的结点。
  • MoveFirst:将Current指针移动到链表的头部。
  • MovePrevious:将Current指针向前移动一位。
  • MoveNext:将Current指针向后移动一位。
public class LinkedList
{private static Node _head;private static Node _current;public LinkedList(){_head = null;_tail = null;_current = null;}public static void Append(object data){var newNode = new Node(data);if (_head == null){_head = newNode;_tail = newNode;}else{_tail.Next = newNode;newNode.Previous = _tail;_tail = newNode;}}public static void MoveFirst(){if (_head != null){_current = _head;}}public static void MovePrevious(){if (_current != null && _current.Previous != null){_current = _current.Previous;}}public static void MoveNext(){if (_current != null && _current.Next != null){_current = _current.Next;}}
}

3.再实现删除方法

        要实现删除操作,添加一个名为 Delete 的方法。在该方法中,需要处理三种情况:删除头部结点、删除尾部结点和删除中间结点。

public static void Delete()
{if (_current == null){return;}// 删除头部结点if (_current == _head){if (_head == _tail){_head = null;_tail = null;}else{_head = _head.Next;_head.Previous = null;}}// 删除尾部结点else if (_current == _tail){_tail = _tail.Previous;_tail.Next = null;}// 删除中间结点else{var nextNode = _current.Next;var previousNode = _current.Previous;nextNode.Previous = previousNode;previousNode.Next = nextNode;}_current = null;
}

        在需要删除当前指向的结点时调用 Delete 方法。注意,在删除结点后,Current 指针会变成 null,需要重新定位到链表的头部或尾部。 

4.再实现Insert 的方法

/// <summary>
/// 在当前位置插入数据,
/// 不对数据排序,也不比较数据
/// </summary>
public static void Insert(int value)
{// 创建一个新的节点var newNode = new Node(value);// 如果链表为空,将新节点设置为头节点if (_head == null){_head = newNode;_current = newNode;return;}// 找到当前节点var current = _current;if (current == null){//current = _head;_current = _head;while (_current.Next != null){_current = _current.Next;}current = _current;}// 在当前位置插入新节点newNode.Next = current.Next;newNode.Previous = current;current.Next = newNode;_current = newNode;
}

        需要在当前节点的后面插入新结点时调用 Insert 方法。注意,在插入新节点后,Current 指针会指向新插入的节点。

5.再增加InsertAscending升序插入

 /// <summary>/// 升序插入方法/// 如果原链表数据未排序,则需先排序然后插入/// </summary>public static Node InsertAscending(int value){Node newNode = new(value);if (_head == null || (int)_head.Data >= value){newNode!.Next = _head;return newNode;}else{Node? previous = _head;Node? current = _head.Next;while (current != null && (int)current.Data < value){previous = current;current = current.Next;}newNode!.Next = current;previous.Next = newNode;}return _head;}

6.再增加 InsertUnAscending 的方法

        添加一个名为 InsertUnAscending 的方法,该方法实现非升序插入功能。这意味着新结点将根据给定的值在链表中找到合适的位置并插入。

/// <summary>
/// 非升序插入节点数据的方法
/// 非升序插入意味着元素不是按升序插入链表中
/// 相反,元素可以以任何顺序插入链表中
/// 具体实现是由程序的需求决定的
/// </summary>
public static void InsertUnAscending(int data)
{var newNode = new Node(data);if (_head == null){_head = newNode;}else{Node? temp = _head;while (temp!.Next != null && (int)temp.Next.Data < data){temp = temp.Next;}newNode.Next = temp.Next;temp.Next = newNode;}
}

        该方法首先检查链表是否为空。如果为空,则将新结点设置为头部、尾部和当前结点。如果新结点的值小于头部结点的值,则将新结点设置为头部,并将其指向原来的头部结点。如果新结点的值大于尾部结点的值,则将新结点设置为尾部,并将其指向原来的尾部结点。否则,我们将遍历链表,找到新结点应该插入的位置,然后将新结点插入到合适的位置。

7.再增加一个Clear方法,清空链表

// 清空链表
public static void Clear()
{_head = null;_tail = null;_current = null;
}

        将链表的头部、尾部和当前结点都设置为 null,从而清空整个链表。

8.再增加GetCurrentValue()方法取得当前的值

// 获取当前结点的值
public static int GetCurrentValue()
{if (_head != null){return (int)_current!.Data;}else{throw new InvalidOperationException("The linked list is empty.");}
}

        在这个修改后的实现中,如果head为null,我们抛出一个InvalidOperationException异常,指示链表为空。

        另外,您还可以根据您的需求选择返回一个默认值或进行其他处理:

public static int GetCurrentValue()
{if (_head != null){return (int)_head.Data;}else{return default; // 或者 return 0;}
}

9.再增加对链表数据冒泡排序SortList方法

/// <summary>
/// 对链表数据冒泡排序
/// </summary>
public static Node? SortList(Node? head)
{if (head == null || head.Next == null){return head;}bool swapped;do{swapped = false;Node? current = head;while (current != null && current.Next != null){if ((int)current.Next.Data < (int)current.Data){(current.Next.Data, current.Data) = (current.Data, current.Next.Data);swapped = true;}current = current.Next;}} while (swapped);return head;
}

三、设计一个Main方法演示上述方法的应用

// 单向链表Main方法
namespace _131_1
{class Program{static void Main(string[] args){ArgumentNullException.ThrowIfNull(args);// 插入结点LinkedList.Append(5);LinkedList.Append(2);LinkedList.Append(8);LinkedList.Append(1);LinkedList.Append(3);// 获取当前结点的值Console.Write("当前结点的值:");Console.WriteLine(LinkedList.GetCurrentValue());// 移动到第一个结点LinkedList.MoveFirst();Console.Write("第一结点的值:");Console.WriteLine(LinkedList.GetCurrentValue());// 移动到下一个结点LinkedList.MoveNext();Console.Write("下一结点的值:");Console.WriteLine(LinkedList.GetCurrentValue());// 移动到上一个结点LinkedList.MovePrevious();Console.Write("上一结点的值:");Console.WriteLine(LinkedList.GetCurrentValue());LinkedList.Print();Console.WriteLine("*初始数据*");// 删除尾首2个结点LinkedList.Delete();LinkedList.MoveFirst();LinkedList.Delete();LinkedList.Print();Console.WriteLine("*删除节点*");// 插入升序结点LinkedList.SortList(LinkedList._head);//先排序LinkedList.InsertAscending(6);LinkedList.InsertAscending(4);LinkedList.InsertAscending(9);LinkedList.Print();Console.WriteLine("*升序插入*");// 插入非升序结点LinkedList.InsertUnAscending(7);LinkedList.InsertUnAscending(3);LinkedList.InsertUnAscending(10);LinkedList.Print();Console.WriteLine("*非升序插入*");// 清空链表LinkedList.Clear();LinkedList.Print();Console.WriteLine();Console.WriteLine("**清空就没有了**");// 插入数据LinkedList.Insert(0);LinkedList.Insert(1);LinkedList.Insert(2);LinkedList.Insert(3);LinkedList.Print();Console.WriteLine("*新数据*");LinkedList.MoveFirst();LinkedList.MoveNext();Console.WriteLine(LinkedList.GetCurrentValue());Console.WriteLine("*********");LinkedList.Insert(5);LinkedList.Print();Console.WriteLine("*插入5*");LinkedList.MovePrevious();LinkedList.Insert(6);LinkedList.Print();Console.WriteLine("**插入6**");}}
}
//运行结果:
/*
当前结点的值:3
第一结点的值:5
下一结点的值:2
上一结点的值:5
5
2
8
1
3
*初始数据*
8
1
3
*删除节点*
1
3
4
6
8
9
*升序插入*
1
3
3
4
6
7
8
9
10
*非升序插入***清空就没有了**
0
1
2
3
*新数据*
1
*********
0
1
5
2
3
*插入5*
0
1
6
5
2
3
**插入6***/

相关文章:

C#单向链表实现:Append,Move,Delete,InsertAscending, InsertUnAscending,Clear

目录 一、链表定义 二、链表设计 1.先定义一个结点类&#xff08;Node&#xff09; 2.再定义链表类&#xff08;LinkedList&#xff09;并依次设计其方法 3.再实现删除方法 4.再实现Insert 的方法 5.再增加InsertAscending升序插入 6.再增加 InsertUnAscending 的方法…...

python基础-基本数据类型深入-2.1

目录 元组 什么是元组&#xff08;tuple&#xff09; 元组练习-1 元组的基本操作 元组常用内建函数 列表和元组的区别与总结 元组练习-2 元组练习-3 元组 什么是元组&#xff08;tuple&#xff09; 与列表&#xff08;list&#xff09;一样&#xff0c;元组&#xff0…...

Android LiveData Cannot add the same observer with different lifecycles

https://www.yxhuang.com/2022/05/29/livedata-add-some-observer-error/ 这篇文章已经解释的很好了。 其实在去年我写的文章&#xff0c; https://blog.csdn.net/jzlhll123/article/details/126593235 中提到了&#xff0c; 其实不论是java或者kotlin&#xff0c;不引用外部的…...

MongoDB聚合运算符:$cmp

文章目录 语法用法举例 $cmp聚合运算符返回连个值的比较结果。 语法 { $cmp: [ <expression1>, <expression2> ] }表达式可以是任何类型&#xff0c;使用标准的BSON比较顺序对不同类型的值进行比较。 用法 $cmp对两个值进行比较&#xff0c;返回&#xff1a; …...

【C++基础知识详细记录】

一、基础知识 C基础知识点的汇总涵盖了许多方面&#xff0c;包括但不限于以下内容&#xff1a; 1. 常量定义 使用#define宏定义常量&#xff1a; #define PI 3.14159265358979323846 // 宏定义一个浮点型常量PI使用const关键字定义常量&#xff1a; const int MAX_SIZE 100;…...

Socket网络编程(五)——TCP数据发送与接收并行

目录 主要实现需求TCP 服务端收发并行重构启动main方法重构重构分离收发消息的操作重构接收消息的操作重构发送消息TCPServer调用发送消息的逻辑监听客户端链接逻辑重构Socket、流的退出与关闭 TCP 客户端收发并行重构客户端 main函数重构客户端接收消息重构客户端发送消息重构…...

2024最新-ubuntu22.04安装最新版QT6.6~6.8教程

​ 1. 在官网下载 online_installer&#xff1a; https://download.qt.io/archive/online_installers/4.7/qt-unified-linux-x64-4.7.0-online.run 或者直接镜像站下载&#xff1a; http://mirrors.ustc.edu.cn/qtproject/archive/online_installers/4.7/qt-unified-linux-x6…...

STM32------分析GPIO寄存器

一、初始LED原理图 共阴极led LED发光二极管&#xff0c;需要有电流通过才能点亮&#xff0c;当有电压差就会产生电流 二极管两端的电压差超过2.7v就会有电流通过 电阻的作用 由于公式IV/R 不加电阻容易造成瞬间电流无穷大 发光二极管工作电流为10-20MA 3.3v / 1kΩ 3.…...

数学实验-Matlab使用(1)

使用方法以及笔记均在文件中 class1_func1.m function f class1_func1(x) % f为输出&#xff0c;输出有多个时需要用中括号以矩阵的方式包起来 % x为输入f sin(x)class1_func2.m function [a,b,u,v] class1_func2(x,y)[a,b] eig(x)[u,v] eig(y)class1.m % 当语句后有…...

kafka文件存储机制和消费者

1.broker文件存储机制 去查看真正的存储文件&#xff1a; 在/opt/module/kafka/datas/ 路径下 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 如果是6415那么这个会存储在563的log文件之中&#xff0c;因为介于6410和10090之间。 2.…...

《汇编语言》- 读书笔记 - 第15章-外中断

《汇编语言》- 读书笔记 - 第15章-外中断 15.1 接口芯片和端口15.2 外中断信息1. 可屏蔽中断&#xff08;Maskable Interrupt&#xff09;2. 不可屏蔽中断&#xff08;Non-Maskable Interrupt&#xff09;设计思想 15.3 PC 机键盘的处理过程1. 键盘输入2. 引发 9 号中断3. 执行…...

【Vue3】CSS 新特性

:slotted <template> <!-- App.vue--><Son ><div class"a">我要插入了</div></Son> </template><script setup lang"ts"> import Son from ./components/Son.vue </script><style></sty…...

四信水电站泄洪预警方案,精准提升防汛应急水平

2022年5月水利部办公厅发布《关于开展水库泄洪设施专项排查整改的紧急通知》&#xff0c;为坚决贯彻落实关于水库大坝安全的重要指示批示精神、关于保障水库泄洪通道通畅的批示要求&#xff0c;全力防范水库可能出现的重大险情&#xff0c;确保水库安全度汛。 2023年3月国家能源…...

k8s中容器的调度与创建:CRI,cgroup

container调度与创建 选自&#xff1a;K8s、CRI与container - packy的文章 - 知乎 https://zhuanlan.zhihu.com/p/102897620 Cgroup创建&#xff1a; cgexec -g cpu,memory:$UUID \ > unshare -uinpUrf --mount-proc \ > sh -c "/bin/hostname $UUID &…...

Unity安装与简单设置

安装网址&#xff1a;https://unity.cn 设置语言&#xff1a; 设置安装位置&#xff1a;否则C盘就会爆了 获取一个个人的资格证&#xff1a; 开始安装&#xff1a; 安装完毕。 添加模块&#xff1a;例如简体中文 新建项目&#xff1a; 布局2*3、单栏布局、 设置…...

数据库的介绍、分类、作用和特点

数据库是用来存储、管理和检索数据的集合系统。根据数据处理模型的不同&#xff0c;数据库可以分为多种类型&#xff0c;主要包括&#xff1a; 1、关系型数据库&#xff08;RDBMS&#xff09;&#xff1a; 介绍&#xff1a;关系型数据库使用表格形式来存储数据&#xff0c;并通…...

【Unity】机器人末端执行器仿真

机械手臂的末端执行器使用多项式来计算转动角度可能有几个原因&#xff1a; 精确控制&#xff1a;机械臂的运动通常需要高度的精确性&#xff0c;特别是在精密工作或复杂运动轨迹的情况下。多项式&#xff0c;特别是高阶的&#xff0c;可以很好地近似复杂的非线性关系和运动轨迹…...

更换个人开发环境后,pycharm连接服务器报错Authentication failed

原因&#xff1a;服务器中更换个人开发环境后&#xff0c;密码变了。 解决&#xff1a;在pycharm中修改服务器开发环境密码即可。 1 找到Tools-Depolyment-Configuration 2 点击SSH Configuration后的省略号 3 修改这里面的Password即可...

E - Bad Juice

解题思路 由于最后返回一个01字符串表示所选人的状态要求人数最少&#xff0c;即字符串长度最少而要用最少的字符&#xff0c;找出则返回的字符为二进制下的编号这样利用了所有的01字符号人表示二进制下位的情况注意对于2的次方项&#xff0c;只需要有位&#xff0c;可以用位均…...

用HTML5的<canvas>元素实现刮刮乐游戏

用HTML5的&#xff1c;canvas&#xff1e;元素实现刮刮乐游戏 用HTML5的<canvas>元素实现刮刮乐&#xff0c;要求&#xff1a;将上面的“图层”的图像可用鼠标刮去&#xff0c;露出下面的“图层”的图像。 示例从简单到复杂。 简单示例 准备两张图像&#xff0c;我这…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI

前一阵子在百度 AI 开发者大会上&#xff0c;看到基于小智 AI DIY 玩具的演示&#xff0c;感觉有点意思&#xff0c;想着自己也来试试。 如果只是想烧录现成的固件&#xff0c;乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外&#xff0c;还提供了基于网页版的 ESP LA…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

保姆级【快数学会Android端“动画“】+ 实现补间动画和逐帧动画!!!

目录 补间动画 1.创建资源文件夹 2.设置文件夹类型 3.创建.xml文件 4.样式设计 5.动画设置 6.动画的实现 内容拓展 7.在原基础上继续添加.xml文件 8.xml代码编写 (1)rotate_anim (2)scale_anim (3)translate_anim 9.MainActivity.java代码汇总 10.效果展示 逐帧…...

Mysql故障排插与环境优化

前置知识点 最上层是一些客户端和连接服务&#xff0c;包含本 sock 通信和大多数jiyukehuduan/服务端工具实现的TCP/IP通信。主要完成一些简介处理、授权认证、及相关的安全方案等。在该层上引入了线程池的概念&#xff0c;为通过安全认证接入的客户端提供线程。同样在该层上可…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录

#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...