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>元素实现刮刮乐,要求:将上面的“图层”的图像可用鼠标刮去,露出下面的“图层”的图像。 示例从简单到复杂。 简单示例 准备两张图像,我这…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
K8S认证|CKS题库+答案| 11. AppArmor
目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作: 1)、切换集群 2)、切换节点 3)、切换到 apparmor 的目录 4)、执行 apparmor 策略模块 5)、修改 pod 文件 6)、…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
MySQL:分区的基本使用
目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区(Partitioning)是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分(分区)可以独立存储、管理和优化,…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
