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.先定义一个结点类(Node) 2.再定义链表类(LinkedList)并依次设计其方法 3.再实现删除方法 4.再实现Insert 的方法 5.再增加InsertAscending升序插入 6.再增加 InsertUnAscending 的方法…...
python基础-基本数据类型深入-2.1
目录 元组 什么是元组(tuple) 元组练习-1 元组的基本操作 元组常用内建函数 列表和元组的区别与总结 元组练习-2 元组练习-3 元组 什么是元组(tuple) 与列表(list)一样,元组࿰…...
Android LiveData Cannot add the same observer with different lifecycles
https://www.yxhuang.com/2022/05/29/livedata-add-some-observer-error/ 这篇文章已经解释的很好了。 其实在去年我写的文章, https://blog.csdn.net/jzlhll123/article/details/126593235 中提到了, 其实不论是java或者kotlin,不引用外部的…...
MongoDB聚合运算符:$cmp
文章目录 语法用法举例 $cmp聚合运算符返回连个值的比较结果。 语法 { $cmp: [ <expression1>, <expression2> ] }表达式可以是任何类型,使用标准的BSON比较顺序对不同类型的值进行比较。 用法 $cmp对两个值进行比较,返回: …...
【C++基础知识详细记录】
一、基础知识 C基础知识点的汇总涵盖了许多方面,包括但不限于以下内容: 1. 常量定义 使用#define宏定义常量: #define PI 3.14159265358979323846 // 宏定义一个浮点型常量PI使用const关键字定义常量: const int MAX_SIZE 100;…...
Socket网络编程(五)——TCP数据发送与接收并行
目录 主要实现需求TCP 服务端收发并行重构启动main方法重构重构分离收发消息的操作重构接收消息的操作重构发送消息TCPServer调用发送消息的逻辑监听客户端链接逻辑重构Socket、流的退出与关闭 TCP 客户端收发并行重构客户端 main函数重构客户端接收消息重构客户端发送消息重构…...
2024最新-ubuntu22.04安装最新版QT6.6~6.8教程
1. 在官网下载 online_installer: https://download.qt.io/archive/online_installers/4.7/qt-unified-linux-x64-4.7.0-online.run 或者直接镜像站下载: http://mirrors.ustc.edu.cn/qtproject/archive/online_installers/4.7/qt-unified-linux-x6…...
STM32------分析GPIO寄存器
一、初始LED原理图 共阴极led LED发光二极管,需要有电流通过才能点亮,当有电压差就会产生电流 二极管两端的电压差超过2.7v就会有电流通过 电阻的作用 由于公式IV/R 不加电阻容易造成瞬间电流无穷大 发光二极管工作电流为10-20MA 3.3v / 1kΩ 3.…...
数学实验-Matlab使用(1)
使用方法以及笔记均在文件中 class1_func1.m function f class1_func1(x) % f为输出,输出有多个时需要用中括号以矩阵的方式包起来 % 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文件存储机制 去查看真正的存储文件: 在/opt/module/kafka/datas/ 路径下 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 如果是6415那么这个会存储在563的log文件之中,因为介于6410和10090之间。 2.…...
《汇编语言》- 读书笔记 - 第15章-外中断
《汇编语言》- 读书笔记 - 第15章-外中断 15.1 接口芯片和端口15.2 外中断信息1. 可屏蔽中断(Maskable Interrupt)2. 不可屏蔽中断(Non-Maskable Interrupt)设计思想 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月水利部办公厅发布《关于开展水库泄洪设施专项排查整改的紧急通知》,为坚决贯彻落实关于水库大坝安全的重要指示批示精神、关于保障水库泄洪通道通畅的批示要求,全力防范水库可能出现的重大险情,确保水库安全度汛。 2023年3月国家能源…...
k8s中容器的调度与创建:CRI,cgroup
container调度与创建 选自:K8s、CRI与container - packy的文章 - 知乎 https://zhuanlan.zhihu.com/p/102897620 Cgroup创建: cgexec -g cpu,memory:$UUID \ > unshare -uinpUrf --mount-proc \ > sh -c "/bin/hostname $UUID &…...
Unity安装与简单设置
安装网址:https://unity.cn 设置语言: 设置安装位置:否则C盘就会爆了 获取一个个人的资格证: 开始安装: 安装完毕。 添加模块:例如简体中文 新建项目: 布局2*3、单栏布局、 设置…...
数据库的介绍、分类、作用和特点
数据库是用来存储、管理和检索数据的集合系统。根据数据处理模型的不同,数据库可以分为多种类型,主要包括: 1、关系型数据库(RDBMS): 介绍:关系型数据库使用表格形式来存储数据,并通…...
【Unity】机器人末端执行器仿真
机械手臂的末端执行器使用多项式来计算转动角度可能有几个原因: 精确控制:机械臂的运动通常需要高度的精确性,特别是在精密工作或复杂运动轨迹的情况下。多项式,特别是高阶的,可以很好地近似复杂的非线性关系和运动轨迹…...
更换个人开发环境后,pycharm连接服务器报错Authentication failed
原因:服务器中更换个人开发环境后,密码变了。 解决:在pycharm中修改服务器开发环境密码即可。 1 找到Tools-Depolyment-Configuration 2 点击SSH Configuration后的省略号 3 修改这里面的Password即可...
E - Bad Juice
解题思路 由于最后返回一个01字符串表示所选人的状态要求人数最少,即字符串长度最少而要用最少的字符,找出则返回的字符为二进制下的编号这样利用了所有的01字符号人表示二进制下位的情况注意对于2的次方项,只需要有位,可以用位均…...
用HTML5的<canvas>元素实现刮刮乐游戏
用HTML5的<canvas>元素实现刮刮乐游戏 用HTML5的<canvas>元素实现刮刮乐,要求:将上面的“图层”的图像可用鼠标刮去,露出下面的“图层”的图像。 示例从简单到复杂。 简单示例 准备两张图像,我这…...
iOSAppHook从零开始:5步快速搭建iOS逆向开发环境
iOSAppHook从零开始:5步快速搭建iOS逆向开发环境 【免费下载链接】iOSAppHook 专注于非越狱环境下iOS应用逆向研究,从dylib注入,应用重签名到App Hook 项目地址: https://gitcode.com/gh_mirrors/io/iOSAppHook iOSAppHook是专注于非越…...
AI编程工具崛起:重塑软件行业格局与挑战
GitHub Copilot开启AI编程辅助先河早在2021年春天,在全世界知晓“ChatGPT”之前18个月,微软就与非营利组织OpenAI合作推出了首款产品——GitHub Copilot。这是一款辅助工具,能在开发者编写代码时,尝试为他们自动补全代码片段和行。…...
优化Betweenness Centrality计算的实用技巧
1. 理解Betweenness Centrality的核心概念 Betweenness Centrality(中介中心性)是图论中衡量节点重要性的关键指标之一。简单来说,它统计的是一个节点在所有最短路径中出现的频率。想象一下城市交通网络中的关键枢纽站,即使这个站…...
SenseVoice Small实战应用:视频内容打标,自动生成文字摘要和情感倾向
SenseVoice Small实战应用:视频内容打标,自动生成文字摘要和情感倾向 1. 引言:当视频内容遇上“读心术” 想象一下,你手头有几百小时的视频素材,可能是会议录像、课程录播、用户访谈,或是社交媒体上的海量…...
龙芯k - 走马观碑组VLLX驱动移植慌
一、什么是urllib3? urllib3 是一个用于处理 HTTP 请求和连接池的强大、用户友好的 Python 库。 它可以帮助你: 发送各种 HTTP 请求(GET, POST, PUT, DELETE等)。 管理连接池,提高网络请求效率。 处理重试和重定向。 支…...
如何彻底移除Windows Defender:完整权限修复与系统优化指南
如何彻底移除Windows Defender:完整权限修复与系统优化指南 【免费下载链接】windows-defender-remover A tool which is uses to remove Windows Defender in Windows 8.x, Windows 10 (every version) and Windows 11. 项目地址: https://gitcode.com/gh_mirror…...
彻底搞懂Type Challenges中的Chunk类型:从入门到精通
彻底搞懂Type Challenges中的Chunk类型:从入门到精通 【免费下载链接】type-challenges Collection of TypeScript type challenges with online judge 项目地址: https://gitcode.com/GitHub_Trending/ty/type-challenges Type Challenges是一个专注于TypeS…...
VS Code官宣全新AI工具:VS Code Agents!
🎯 一句话总结 VSCode 1.115 带来了 Agents 专属独立应用,🚀 主角登场:VS Code Agents 独立应用 这是什么? 不再是 VSCode 里的一个侧边栏,而是一个完全独立的 companion app,专为 Agent 开发打…...
【关注合作源码】-家政服务管理系统|家政预约|家政平台
博主介绍: 所有项目都配有从入门到精通的安装教程,可二开,提供核心代码讲解,项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频;项目的界面和功能都可以定制,包安装运行ÿ…...
Miaow插件图标库管理:从导入到分类的完整工作流
Miaow插件图标库管理:从导入到分类的完整工作流 【免费下载链接】Miaow A set of plugins for Sketch include drawing links & marks, UI Kit & Color sync, font & text replacing. 项目地址: https://gitcode.com/gh_mirrors/mi/Miaow Miaow是…...
