C#【进阶】常用泛型数据结构类

news2024/11/24 23:11:02

常用泛型数据结构类

在这里插入图片描述

文章目录

    • 常用泛型数据结构类
      • 1、List
        • 1、List的本质
        • 2、声明
        • 3、增删查改
        • 4、遍历
          • 思考 存储基类类型列表
      • 2、Dictionary
        • 1、Dictionary的本质
        • 2、声明
        • 3、增删查改
        • 4、遍历
          • 思考1 数字对应的大写
          • 思考 2 字母出现的次数
      • 3、顺序存储和链式存储
        • 1、数据结构
        • 2、线性表
        • 3、顺序存储
        • 4、链式存储
        • 5、自己实现一个最简单的单向链表
        • 6、顺序存储和链式存储的优缺点
          • 思考 双向链表
      • 4、Linkedlist
        • 1、LinkedList
        • 2、声明
        • 3、增删查改
        • 4、遍历
      • 5、泛型栈和队列
      • 总结 数据用法

1、List

1、List的本质
List是C#封装好的类,本质是一个可变类型的泛型数组
2、声明
List<int> list1 = new List<int>();
List<string> list2 = new List<string>();
List<string> listStr = new List<string>();
3、增删查改
增
    list1.Add(11);
    list2.AddRange(listStr);
	list1.Insert(0,66);//1.移除指定元素
    list1.Remove(11);
    //2、移除指定位置元素
    list1.RemoveAt(0);
    //3、清空
    list1.Clear();//1、查看指定位置元素
    Console.WriteLine(list1[0]);
    //2、查看元素是否存在
    if (list1.Contains(11))
    {
        Console.WriteLine("存在");
    }
    //3、正向查找元素位置
    int index = list1.IndexOf(11);
    Console.WriteLine(index);
    //4、反向查找元素位置
    index = list1.LastIndexOf(11);
    Console.WriteLine(index);
改
    list1[0] = 22;
4、遍历
//长度
Console.WriteLine(list1.Count);
//容量
Console.WriteLine(list1.Capacity);
//for循环遍历
for (int i = 0; i < list1.Count; i++)
{
    Console.WriteLine(list1[i]);
}
//迭代器遍历
foreach (int i in list1)
{
    Console.WriteLine(i);
}
思考 存储基类类型列表
//一个Monster基类,Boss和Gablin类继承它
//在怪物类的构造函数中,将其存储到一个怪物List中
//遍历列表可以让Boss和Gablin对象产生不同攻击

Boss boss1 = new Boss();
Boss boss2 = new Boss();
Gablin Gablin1 = new Gablin();
Gablin Gablin2 = new Gablin();
for (int i = 0; i < Monster.monsters.Count; i++)
{
    Monster.monsters[i].Atk();
}
abstract class Monster
{
    public static List<Monster> monsters = new List<Monster>();
    public Monster()
    {
        monsters.Add(this);
    }
    public abstract void Atk();
}
class Gablin : Monster
{
    public override void Atk()
    {
        Console.WriteLine("哥布林的攻击");
    }
}
class Boss : Monster
{
    public override void Atk()
    {
        Console.WriteLine("Boss的攻击");
    }
}

2、Dictionary

1、Dictionary的本质
可以将Dictionary理解为:拥有泛型的Hashtable
它是基于键的哈希代码组织起来的键值对
键值对类型从Hashtable的object变为了可以自己指定的泛型
2、声明
Dictionary<int,string> dictionary = new Dictionary<int,string>();
3、增删查改
//不能出现相同名的键
    dictionary.Add(1, "aaa");
    dictionary.Add(2, "bbb");
    dictionary.Add(3, "ccc");//1、只能通过键去删除
    dictionary.Remove(3);
    //2、清空
    dictionary.Clear();//1、通过键查看值,键找不到报错
    Console.WriteLine(dictionary[2]);
    //2、查看是否存在
    //根据键检测
    if (dictionary.ContainsKey(2))
    {
        Console.WriteLine("存在");
    }
    //根据值检测
    if (dictionary.ContainsValue("bbb"))
    {
        Console.WriteLine("存在");
    }
改
    dictionary[1]="666";
4、遍历
1、遍历所有键
    foreach (int item in dictionary.Keys)
    {
        Console.WriteLine(item);
        Console.WriteLine(dictionary[item]);
    }
2、遍历所有值
    foreach(string item in dictionary.Values)
    {
        Console.WriteLine(item);
    }
3、键值对遍历
    foreach(KeyValuePair<int,string> pair in dictionary)
    {
        Console.WriteLine(pair);
    }
思考1 数字对应的大写
//使用字典存储0~9的数字对应的大写文字
//提示用户输入一个不超过三位的数,提供一个方法,返回数的大写
try
{
    Console.WriteLine("输入三位数");
    Console.WriteLine(GetInfo(int.Parse(Console.ReadLine())));
}
catch
{

    Console.WriteLine("wrong");
}

string GetInfo(int num)
{
    Dictionary<int, string> dictionary = new Dictionary<int, string>();
    dictionary.Add(0, "零");
    dictionary.Add(1, "壹");
    dictionary.Add(2, "贰");
    dictionary.Add(3, "叁");
    dictionary.Add(4, "肆");
    dictionary.Add(5, "伍");
    dictionary.Add(6, "陆");
    dictionary.Add(7, "柒");
    dictionary.Add(8, "捌");
    dictionary.Add(9, "玖");
    int b = num / 100;
    string str = "";
    if (b != 0)
    {
        str += dictionary[b];
    }

    int s = num % 100 / 10;
    if (s != 0 || str != "")
    {
        str += dictionary[s];
    }

    int g = num % 10;
    str += dictionary[g];
    return str;
}
思考 2 字母出现的次数
//计算每个字母出现的次数“Welcome to Unity World!”,使用字典存储,最后遍历,不区分大小写
Dictionary<char,int> dictionary = new Dictionary<char,int>();
string str = "Welcome to Unity World!";
str = str.ToLower();
for (int i = 0; i < str.Length; i++)
{
    if (dictionary.ContainsKey(str[i]))
    {
        dictionary[str[i]]++;
    }
    else
    {
        dictionary.Add(str[i], 1);
    }
}
foreach (char c in dictionary.Keys)
{
    Console.WriteLine("{0}出现了{1}次", c, dictionary[c]);
}

3、顺序存储和链式存储

1、数据结构
数据结构是计算机存储、组织数据的规则
数据结构是指相互之间存在一种或多种特定关系的数据元素的集合
存储数据和表示数据之间关系的规则
常用的数据结构
数组、栈、队列、链表、树、图、堆、散列表
2、线性表
线性表是一种数据结构,是由n个具有相同特性的数据元素的有限序列
例如:数组、ArrayList、Stack、Queue、链表
3、顺序存储

顺序存储和链式存储是数据结构中两种存储结构

数组、Stack、Queue、List、ArrayList 顺序存储
数组、Stack、Queue的组织规则不同
顺序存储:用一组地址连续的存储单元依次存储线性表的各个数据元素
4、链式存储
单向链表、双向链表、循环链表	链式存储
链式存储(链接存储):用一组任意的存储单元存储线性表中的各个数据元素
5、自己实现一个最简单的单向链表
LinkedList<int> link = new LinkedList<int>();
link.Add(1);
link.Add(2);
link.Add(3);
link.Add(4);

LinkedNode<int> node = link.head;
while (node != null)
{
    Console.WriteLine(node.value);
    node = node.nextNode;
}

link.Remove(2);
node = link.head;
while (node != null)
{
    Console.WriteLine(node.value);
    node = node.nextNode;
}

link.Add(5);
node = link.head;
while (node != null)
{
    Console.WriteLine(node.value);
    node = node.nextNode;
}
/// <summary>
/// 单向链表节点
/// </summary>
/// <typeparam name="T"></typeparam>
class LinkedNode<T>
{
    public T value;
    public LinkedNode<T> nextNode;

    public LinkedNode(T value)
    {
        this.value = value;
    }
}
/// <summary>
/// 单向链表类 管理
/// </summary>
/// <typeparam name="T"></typeparam>
class LinkedList<T>
{
    public LinkedNode<T> head;
    public LinkedNode<T> last;
    public void Add(T value)
    {
        LinkedNode<T> node = new LinkedNode<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            last.nextNode = node;
            last = node;
        }
    }
    public void Remove(T value) 
    { 
        if(head== null)
        {
            return;
        }
        if (head.value.Equals(value))
        {
            head = head.nextNode;
            if (head == null)
            {
                last = null;
            }
            return;
        }
        LinkedNode<T> node = head;
        while (node.nextNode != null)
        {
            if (node.nextNode.value.Equals(value))
            {
                node.nextNode = node.nextNode.nextNode;
                break;
            }
            node = node.nextNode;
        }
    }
}
6、顺序存储和链式存储的优缺点
增、删:链式存储优于顺序存储
查、改:顺序存储优于链式存储
思考 双向链表
//实现一个双向链表,并提供以下方法和属性
//数据的个数,头节点,尾节点
//增加数据到链表最后
//删除指定位置节点

LinkedList<int> link = new LinkedList<int>();
link.Add(2);
link.Add(3);
link.Add(4);
link.Add(5);
//正向访问
LinkedNode<int> node = link.Head;
while (node != null)
{
    Console.WriteLine(node.value);
    node = node.nextNode;
}

link.RemoveAt(5);

//反向访问
node = link.Last;
while (node != null)
{
    Console.WriteLine(node.value);
    node = node.frontNode;
}

class LinkedNode<T>
{
    public T value;
    public LinkedNode<T> frontNode;
    public LinkedNode<T> nextNode;

    public LinkedNode(T value)
    {
        this.value = value;
    }
}

class LinkedList<T>
{
    private int count;
    private LinkedNode<T> head;
    private LinkedNode<T> last;
    
    public int Count
    {
        get { return count; }
    }

    public LinkedNode<T> Head
    {
        get { return head; }
    }

    public LinkedNode<T> Last
    {
        get { return last; }
    }

    //添加
    public void Add(T value)
    {
        LinkedNode<T> node = new LinkedNode<T>(value);
        if (head == null)
        {
            head = node;
            last = node;
        }
        else
        {
            //添加到尾部
            last.nextNode = node;
            //尾部添加的节点 记录自己的上一个节点
            node.frontNode = last;

            //将新加节点记录为last
            last = node;
        }
        count++;
    }

    //删除
    public void RemoveAt(int index)
    {
        if (index >= count || index < 0)
        {
            Console.WriteLine("删除失败");
            return;
        }
        int tempCount = 0;
        LinkedNode<T> tempNode = head;
        while (true)
        {
            //计数找到对应节点
            if (tempCount == index)
            {
                //移除节点
                if (tempNode.frontNode !=null)
                {
                    tempNode.frontNode.nextNode = tempNode.nextNode;
                }
                if (tempNode.nextNode != null)
                {
                    tempNode.nextNode.frontNode = tempNode.frontNode;
                }
                //若移除了头节点,则将头指向下一个节点
                if (index == 0)
                {
                    head = head.nextNode;
                }
                //将倒数第二个作为尾节点
                else if (index == count-1)
                {
                    last = last.frontNode;
                }
                count--;
                break;           
            }
            //每次下移一位
            tempNode = tempNode.nextNode;
            tempCount++;
        }
    }
}

4、Linkedlist

1、LinkedList
LinkedList是一个C#为我们封装好的类
它的本质是一个可变类型的泛型双向链表
2、声明
//链表LinkedList 链表节点类LinkedListNode
LinkedList<int> link = new LinkedList<int>();
LinkedList<string> link2 = new LinkedList<string>();
3、增删查改
LinkedList<int> link = new LinkedList<int>();1、在链表头部添加元素
    	link.AddFirst(1);
    2、在链表尾部添加元素
		link.AddLast(20);
    3、在某个节点之前添加元素
		LinkedListNode<int> c = link.Find(2);
		link.AddBefore(c, 19);
    4、在某个节点之后添加元素
		link.AddAfter(c, 21);1、移除头节点
    	link.RemoveFirst();
    2、移除尾节点
    	link.RemoveLast();
    3、移除指定节点
        link.Remove(20);1、头节点
    	LinkedListNode<int> first = link.First;
    2、尾节点
        LinkedListNode<int> last = link.Last;
    3、找到指定值节点
    	LinkedListNode<int> node = link.Find(20);
		Console.WriteLine(node.Value);
    4、判断是否存在
        if (link.Contains(20))
        {
            Console.WriteLine("存在");
        }
改
    先得到节点,再该值
    	link.First.Value = 10;
4、遍历
1、foreach遍历
	foreach (int i in link)
    {
        Console.WriteLine(i);
    }
2、通过节点遍历
    从头到尾
    	LinkedListNode<int> nowNode = link.First;
        while (nowNode != null)
        {
            Console.WriteLine(nowNode.Value);
            nowNode = nowNode.Next;
        }
    从尾到头
        nowNode = link.Last;
        while (nowNode != null)
        {
            Console.WriteLine(nowNode.Value);
            nowNode = nowNode.Previous;
        }

5、泛型栈和队列

Stack<int> s = new Stack<int>();
Queue<int> q = new Queue<int>();

总结 数据用法

普通线性表:
    数组、List、LinkedList
        ArrayList:固定的不变的一组数据
        List:经常改变,经常通过下标查找
        LinkedList:不确定长度,经常临时插入改变,查找次数少

先进后出
    Stack
    对于一些可以利用先进后出存储特点的逻辑
    比如:UI面板显隐规则

先进先出
    Queue
    对于一些可以利用先进先出存储特点的逻辑
    比如:消息队列,实时存放,慢慢依次处理

键值对
    Dictionary
    需要频繁查找的,有对应关系的数据
    比如一些数据存储,id对应数据内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1672034.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端铺子-NodeJS后端:基于Node.js构建高效后端服务的探索与实践

一、引言 随着前端技术的快速发展&#xff0c;越来越多的开发者开始关注前后端分离的开发模式。前端铺子作为一个旨在服务前端开发者的开源项目&#xff0c;近期推出了基于Node.js的后端系统。该系统通过整合Node.js、Nodemon和MySQL等技术&#xff0c;为前端开发者提供了一个…

每日一题 城市群的数量

题目解析 城市群数量_牛客题霸_牛客网 当解决这个问题时&#xff0c;首先需要理解题目要求。题目中给出了一个城市之间的邻接矩阵&#xff0c;矩阵中的元素表示城市之间是否直接相连。如果两个城市直接相连&#xff0c;或者通过其他城市间接相连&#xff0c;它们就属于同一个城…

Java面试八股之String s = “String“;和String s = new String(“String“);有什么区别

Java中String s "String";和String s new String("String");有什么区别 字符串字面量&#xff08;"String"&#xff09;&#xff1a; 常量池&#xff1a;使用字面量方式创建字符串时&#xff0c;Java虚拟机&#xff08;JVM&#xff09;会在运…

数组 | 双指针经典题目

Leetcode977&#xff1a;有序数组的平方 . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/squares-of-a-sorted-array/d…

AI2024(64bit) Adobe Illustrator 软件安装包下载

AI2024(64bit) Adobe Illustrator 软件安装包下载地址&#xff1a; 百度网盘下载https://pan.baidu.com/s/1C10-2JVN1rxFF5VFRuV2Yw?pwdSIMS 在创意设计的浩瀚宇宙中&#xff0c;Adobe Illustrator 2024如同一颗璀璨新星&#xff0c;以其无与伦比的创新功能和优化体验&#x…

AI翻唱+视频剪辑全流程实战

目录 一、AI翻唱之模型训练 &#xff08;1&#xff09;模型部署 &#xff08;2&#xff09;数据集制作——搜集素材 &#xff08;3&#xff09;数据集制作——提升音频质量 方法一&#xff1a;使用RVC提供的音频处理功能。 方法二&#xff1a;可以使用音频剪辑工具Ad…

vivado Kintex UltraScale+ 配置存储器器件

Kintex UltraScale 配置存储器器件 下表所示闪存器件支持通过 Vivado 软件对 Kintex UltraScale 器件执行擦除、空白检查、编程和验证等配置操作。 本附录中的表格所列赛灵思系列非易失性存储器将不断保持更新 &#xff0c; 并支持通过 Vivado 软件对其中所列非易失性存…

CommandLineRunner和ApplicationRunner接口实现类中run方法发生异常导致spring程序关闭

今天其他组的一个程序在k8s中启动报错&#xff0c;启动之后立马就关闭了。我去看日志&#xff0c;发现最后面报了一个UnknownHostException异常&#xff0c;感觉是这个原因导致的&#xff0c;然后查看异常栈。定位到一个CommandLineRunner接口实现类&#xff0c;这个实现类里面…

一道dp错题

dis(a,b)就是两点之间的距离公式 那么这道题该怎么解呢,.先看数据范围x,y<1e4,so,18个点两点之间距离最大18*1e4*sqrt(2)<2^18,所以如果跳过的点大于18个点,那么显然一个区间内最多不会跳跃超过17个点 现在我们想知道前i个点跳跃几次在哪跳跃能够达到最小花费,不妨设跳…

STM32(GPIO)

GPIO简介 GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口 引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V 输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等 输入模式下可读取端口的高低电…

迄今为止最全- 前端性能优化

简介 当我们说前端性能优化的时候&#xff0c;指的可能是不同场景的性能优化。前端涉及性能优化的场景主要有&#xff1a; 项目构建性能优化 页面性能优化 加载时性能优化 运行时性能优化 构建性能主要指构建速度&#xff0c;优化方法和打包工具直接相关&#xff0c;主要…

航空科技:探索飞机引擎可视化技术的新视界

随着航空技术的飞速发展&#xff0c;飞机引擎作为航空器最为关键的部件之一&#xff0c;其性能直接影响到飞机的安全性、经济性和环保性。因此&#xff0c;飞机引擎可视化技术的应用日益成为航空行业研究和发展的热点。 通过图扑将复杂的飞机引擎结构和工作原理以直观、生动的…

[GXYCTF 2019]Ping Ping Ping(内联执行)、[鹤城杯 2021]EasyP ($_SERVER)

目录 [GXYCTF 2019]Ping Ping Ping 内联执行 [鹤城杯 2021]EasyP [PHP_SELF]、$_SERVER[SCRIPT_NAME] 与 $_SERVER[REQUEST_URI] RCE命令注入可参考&#xff1a; RCE漏洞及其绕过——[SWPUCTF 2021 新生赛]easyrce、caidao、babyrce-CSDN博客 [GXYCTF 2019]Ping Ping Pin…

有哪些网络兼职适合大学生参与?揭秘几个简单又实用的兼职机会

有哪些网络兼职适合大学生参与&#xff1f;揭秘几个简单又实用的兼职机会 对于大学生而言&#xff0c;除了专注于学业&#xff0c;利用空余时间参与一些网络兼职&#xff0c;不仅能锻炼个人技能&#xff0c;还能为未来的职业生涯积累宝贵的经验。想象一下&#xff0c;步入社会…

基于SpringBoot + Vue的学生宿舍课管理系统设计与实现+毕业论文(15000字)+开题报告

系统介绍 本系统包含管理员、宿管员、学生三个角色。 管理员&#xff1a;管理宿管员、管理学生、修改密码、维护个人信息。 宿管员&#xff1a;管理公寓资产、管理缴费信息、管理公共场所清理信息、管理日常事务信息、审核学生床位安排信息。 学生&#xff1a;查看公共场所清理…

标准输入输出流(中北大学-程序设计基础(2))

目录 题目 源码 结果示例 题目 输入三角形的三边a,b,c&#xff0c;计算三角形的面积。形成三角形的条件是ab>c,bc>a,ac>b&#xff0c;编写程序&#xff0c;输入a,b,c&#xff0c;检查a,b,c是否满足以上条件&#xff0c;如不满足&#xff0c;由cerr输出有关出错信息…

IDEA设置 | 个性化设置

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a;神马都会亿点点的毛毛张 文章目录 前言IDEA自动生成序列化ID 前言 本篇博客将专注于整理IDEA新UI界面的相关设置 IDEA自动生成序列化ID CtrlAltS快捷键打开设置界面 选择Editor→Inspections…

MyBatis——使用MyBatis完成CRUD

CRUD&#xff1a;Create Retrieve Update Delete 1、insert <insert id"insertCar">insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)values(null,1003,五菱宏光,30.0,2020-09-18,燃油车); </insert> 这样写显然是写死的&#…

大模型微调方法汇总

微调方法 Freeze方法P-tuning方法 prefix-tuningPrompt TuningP-tuning v1P-tuning v2Lora方法 重要相关参数LoRA 的优势Qlora方法 相关参数微调经验 模型选择模型大小选择数据处理微调方案英文模型需要做词表扩充吗&#xff1f;如何避免灾难遗忘大模型的幻觉问题微调后的输出…

2024第八季完美童模 【星光】品牌赛区 【直通】赛 完美收官

2024年5月1日&#xff0c;春风徐徐的【星光品牌赛区】热闹非凡&#xff0c;备受瞩目的第八季完美童模【星光品牌赛区】赛区【直通赛】在这一天正式拉开了帷幕。比赛现场&#xff0c;童模们身着华服&#xff0c;在舞台上演绎了“亚特兰蒂斯”的时尚主题赛。 参赛选手们身着带有海…