C# 数组增加元素_【自学C#】|| 笔记 21 集合续,队列和堆栈

9e4f53fd52637740ed5df9e6f6aad54f.png

一、Queue类:队列

    Queue (队列) 是常见的数据结构之一。

    队列是一种先进先出的结构,即元素从队列尾部插入,从队列的头部移除,类似于日常生活中的站队,先到先得的效果。
    集合中的 Queue 类模拟了队列操作,提供了队列中常用的属性和方法。
    Queue 类提供了 4 个构造方法,如下表所示。

构造方法作用
Queue()创建 Queue 的实例,集合的容量是默认初始容量 32 个元素,使用默认的增长因子
Queue(ICollection col)创建 Queue 的实例,该实例包含从指定实例中复制的元素,并且初始容量与复制的元素个数、增长因子相同
Queue(int capacity) 创建 Queue 的实例,并设置其指定的元素个数,默认增长因子
Queue(int capacity, float growFactor)创建 Queue 的实例,并设置其指定的元素个数和增长因子

    增长因子是指当需要扩大容量时,以当前的容量(capacity)值乘以增长因子(growFactor)的值来自动增加容量。
    下面使用上表中的构造方法来创建 Queue 的实例,代码如下。

//第 1 中构造器Queue queueq1 = new Queue();//第 2 中构造器Queue queueq2 = new Queue(queue1);//第 3 中构造器Queue queueq3 = new Queue(30);//第 4 中构造器Queue queueq4 = new Queue(30, 2);

与上一节《C# ArrayList》中介绍的 ArrayList 类不同,Queue 类不能在创建实例时直接添加值。

Queue类中常用的属性和方法如下表所示。

属性或方法作用
Count属性,获取 Queue 实例中包含的元素个数
void Clear() 清除 Queue 实例中的元素
bool Contains(object obj)判断 Queue 实例中是否含有 obj 元素
void CopyTo(Array array, int index) 将 array 数组从指定索引处的元素开始复制到 Queue 实例中
object Dequeue()移除并返回位于 Queue 实例开始处的对象
void Enqueue(object obj)将对象添加到 Queue 实例的结尾处
object Peek() 返回位于 Queue 实例开始处的对象但不将其移除
object[] ToArray()将 Queue 实例中的元素复制到新数组
void TrimToSize() 将容量设置为 Queue 实例中元素的实际数目
IEnumerator GetEnumerator() 返回循环访问 Queue 实例的枚举数

    (总之就是创建了一个内存空间,类似一个数值,并且默认长度是32。)

    (然后存储方式就像排队一样,从尾部存入,从头部取出使用并移除。中间部分不能进行修改使用。)

    再然后就是一些方法和属性的使用。

    1.例

    创建 Queue 类的实例,模拟排队购电影票的操作。

    根据题目要求,先向队列中加入 3 个元素,然后再依次购票。

    实现代码如下。

class Program{    static void Main(string[] args){        Queue queue = new Queue();        //向队列中加入3为购票人        queue.Enqueue("小张");        queue.Enqueue("小李");        queue.Enqueue("小刘");        Console.WriteLine("购票开始:");        //当队列中没有人时购票结束        while (queue.Count != 0)        {            Console.WriteLine(queue.Dequeue() + "已购票!");        }        Console.WriteLine("购票结束!");    }}

分析:

    首先创建一个Queue 类的队列实例。

    然后通过Enqueue方法追加数据。

    然后通过while循环,进行判断循环。

        Count属性,表示实例中是否存在着元素,也就是队列的长度。

        而且从这里来看,如果什么也不存,默认就是0.

        存1个就是1,再存1个就是2.

        上面存了3个,也就是queue.Count=3.

        queue.Dequeue();取出队列里的元素。

        并且每取出一个,队列里的长度就减1,而且取出的数据也脱离队列,从队列中剔除。

    然后再输出一个最后的结果。

    运行结果:

362c841d47e030f684ec252d71780ebd.png

    从上面的执行效果可以看出,在从队列中取值时与存入队列中的值顺序是相同的。

    2.例

    向 Queue 类的实例中添加 3 个值,在不移除队列中元素的前提下将队列中的元素依次输出。

    根据题目要求,可以使用 ToArray() 方法将 Queue 类的实例中存放的值复制到数组后再遍历数组。

    实现的代码如下。

class Program{    static void Main(string[] args){        Queue queue = new Queue();        queue.Enqueue("aaa");        queue.Enqueue("bbb");        queue.Enqueue("ccc");        object[] obj = queue.ToArray();        foreach(var v in obj)        {            Console.WriteLine(v);        }    }}

分析:

    创建一个队列实例。

    然后往队列中存入3个元素。

    然后第9行,将队列复制到Object类型的数组中。

        .ToArray()方法,将队列变成数组,并赋值到Object类型的数组变量中。

    然后就直接通过foreach进行数组遍历。

cede49456ed6934f69e54047ecca8106.png

    队列,就像排队一样。先存入的,就会先输出。(毕竟不允许插队!)

    3.例

    除了使用 ToArray() 方法以外,还可以使用 GetEnumerator() 方法来遍历,实现的代码如下。

class Program{    static void Main(string[] args){        Queue queue = new Queue();        queue.Enqueue("aaa");        queue.Enqueue("bbb");        queue.Enqueue("ccc");        IEnumerator enumerator = queue.GetEnumerator();        while (enumerator.MoveNext())        {            Console.WriteLine(enumerator.Current);        }    }}

分析:

    同样定义了一个队列,并存入3个元素。

    然后又定义了一个IEnumerator类型变量,应该是一个接口。

            queue.GetEnumerator()返回循环访问 Queue 实例的枚举数。

    通过while循环;

        enumerator.MoveNext()返回的是true。

        应该是enumerator变量内存在元素,就是true。

        enumerator.Current:则是将元素里的元素取出。

    9~13行,已经属于固定搭配吧!

39204a48f02633444a4304f5c768168f.png

    效果与使用 ToArray() 所示的效果相同。在实际应用中,我们可以自由选择上面两种方法。

二、Stack类:堆栈

    Stack (栈)是常见的数据结构之一,栈是一种先进后出的结构,即元素从栈的尾部插入,从栈的尾部移除,类似于日常生活中搬家的时候装车,先装上车的东西要后拿下来。
    集合中的 Stack 类模拟了栈操作,提供了栈中常用的属性和方法。
    Stack 类提供了 3 种构造方法,如下表所示。

构造方法作用
Stack()使用初始容量创建 Stack 的对象
Stack(ICollection col) 创建 Stack 的实例,该实例包含从指定实例中复制的元素,并且初始容量与复制的元素个数、增长因子相同
Stack(int capacity)创建 Stack 的实例,并设置其初始容量

Stack 类中的常用属性和方法如下表所示。

属性或方法作用
Push(object obj)向栈中添加元素,也称入栈
object Peek()用于获取栈顶元素的值,但不移除栈顶元素的值
object Pop()用于移除栈顶元素的值,并移除栈顶元素
Clear()从 Stack 中移除所有的元素
Contains(object obj)判断某个元素是否在 Stack 中
object[] ToArray()复制 Stack 到一个新的数组中

    (总之,堆栈就像是干草堆,或者说是枪战片里给弹匣压子弹。)

    (每存一个元素,就会在数据的最顶端,使用时也会从最顶端的元素进行取出使用,并脱离这个堆栈。)

    (还真像压子弹一样,压完后上膛,射出的子弹就是最后压上前的那个。)

    堆栈的特性是,后存入的元素,被使用时会先调用。

    1.例

    下面通过实例来演示 Stack 类的使用。

    创建一个栈(Stack),模拟餐馆盘子的存取。

    根据题目要求,先在栈中按顺序放置 5 个盘子,再将所有盘子取出,取盘子时应先取最上面的盘子,与栈的存取原理一致。具体的代码如下。

class Program{    static void Main(string[] args){        Stack stack = new Stack();        //向栈中存放元素        stack.Push("1 号盘子");        stack.Push("2 号盘子");        stack.Push("3 号盘子");        stack.Push("4 号盘子");        stack.Push("5 号盘子");        Console.WriteLine("取出盘子:");        //判断栈中是否有元素        while(stack.Count != 0)        {            //取出栈中的元素            Console.WriteLine(stack.Pop());        }    }}

分析:

    创建一个堆栈。

    Push()方法,就是往里面存储元素,压栈,压子弹。

    然后通过while循环语句进行循环遍历。

    Count属性,是计算堆栈里面的个数。

    如果不等于0,就循环。

    Pop()方法,表示取出堆栈里面的元素,出栈,射子弹。

运行结果:

35a598eb013648b383e07b74c68968d8.png

    可以看出,先存入的数据元素,反而会被最后输出。

    就像弹匣那样,上子弹时,先放入的子弹在最底下,而打枪时,先射出的则是最后存入的那个子弹。

ee2ea12a873e3aa984ece9c10cac8767.png

三、Hashtable类:哈希表(散列表)

    Hashtable 类实现了 IDictionary 接口,集合中的值都是以键值对的形式存取的。
    C# 中的 Hashtable 称为哈希表,也称为散列表,在该集合中使用键值对(key/value)的形式存放值。
    换句话说,在 Hashtable 中存放了两个数组,一个数组用于存放 key 值,一个数组用于存放 value 值。
    此外,还提供了根据集合中元素的 key 值查找其对应的 value 值的方法。

    Hashtable 类提供的构造方法有很多,最常用的是不含参数的构造方法,即通过如下代码来实例化 Hashtable 类。

Hashtable 对象名 = new Hashtable ();

Hashtable 类中常用的属性和方法如下表所示。

属性或方法作用
Count集合中存放的元素的实际个数
void Add(object key,object value)向集合中添加元素
void Remove(object key)根据指定的 key 值移除对应的集合元素
void Clear()清空集合
ContainsKey (object key)判断集合中是否包含指定 key 值的元素
ContainsValue(object value)判断集合中是否包含指定 value 值的元素

    (总之,是一个类似键值对的数据类型。)

    类似a{“a”:“aa”,“b”:“bb”,“c”:“cc”‍}这样的形式。

    1.例

    使用 Hashtable 集合实现图书信息的添加、查找以及遍历的操作。

    根据题目要求,先向 Hashtable 集合中添加 3 个值,再根据所输入的 key 值查找图书名称,最后遍历所有的图书信息,代码如下。

class Program{    static void Main(string[] args)    {        Hashtable ht = new Hashtable();        ht.Add(1, "计算机基础");        ht.Add(2, "C#高级编程");        ht.Add(3, "数据库应用");        Console.WriteLine("请输入图书编号");        int id = int.Parse(Console.ReadLine());        bool flag = ht.ContainsKey(id);        if (flag)        {            Console.WriteLine("您查找的图书名称为:{0}", ht[id].ToString());        }        else        {            Console.WriteLine("您查找的图书编号不存在!");        }        Console.WriteLine("所有的图书信息如下:");        foreach(DictionaryEntry d in ht)        {            int key = (int)d.Key;            string value = d.Value.ToString();            Console.WriteLine("图书编号:{0},图书名称:{1}", key, value);        }    }}

分析:

    首先定义一个哈希类。

    然后添加元素。

    Add()方法,则是添加元素的方法。

        第一个参数是,键key;

        第二个参数是,值value。

    第10行,是手动输入一个int类型的数,也就是id号。

        其实也就是哈希类中的键。

    第11行,

    ht.ContainsKey(id);判断集合中是否包含指定 key 值的元素。

    12~15行,

        因为11行返回的是一个布尔值。

        所以在12行进行if语句判断。

        ht[id].ToString();

            首先是ht[id],表示取出id键的值元素。

            ht是哈希类型的变量,里面存着键值对的数据。

            id是哈希数据里的键key,也就相当于数组中的元素下标。

            .ToString()方法,是将取出来的元素变成字符串类型。

        如果if语句为假,就输出"您查找的图书编号不存在!"。

    21~26行

        遍历哈希类型里面的数据。

        由此可以看出,哈希类的数据类型是DictionaryEntry。

        然后强行把键key的类型转换成int类型,也是值类型。

        哈希类的值数据value,通过 .ToString()方法转换成了字符串,也就是引用类型。

        然后结合foreach循环输出。

504724839b9917e2616f02d1d9b19584.png

    从上面的执行效果可以看出,在使用 Hashtable 时能同时存放 key/value 的键值对,由于 key 值是唯一的,因此可以根据指定的 key 值查找 value 值。

    并且输出遍历的方式,是堆栈的形式。

四、SortedList类:有序列表

    SortedList 类实现了 IDictionary 接口 ,集合中的值都是以键值对的形式存取的。
    C# SortedList 称为有序列表,按照 key 值对集合中的元素排序。
    SortedList 集合中所使用的属性和方法与上一节《C# Hashtable》中介绍的 Hashtable 比较类似,这里不再赘述。

    1.例

    使用 SortedList 实现挂号信息的添加、查找以及遍历操作。

    根据题目要求,向 SortedList 集合中添加 3 位挂号信息(挂号编号、姓名),并根据患者编号查找患者姓名,遍历所有的挂号信息。具体的代码如下。

class Program{    static void Main(string[] args)    {        SortedList sortList = new SortedList();        sortList.Add(1, "小张");        sortList.Add(2, "小李");        sortList.Add(3, "小刘");        Console.WriteLine("请输入挂号编号:");        int id = int.Parse(Console.ReadLine());        bool flag = sortList.ContainsKey(id);        if (flag)        {            string name = sortList[id].ToString();            Console.WriteLine("您查找的患者姓名为:{0}", name);        }        else        {            Console.WriteLine("您查找的挂号编号不存在!");        }        Console.WriteLine("所有的挂号信息如下:");        foreach(DictionaryEntry d in sortList)        {            int key = (int)d.Key;            string value = d.Value.ToString();            Console.WriteLine("挂号编号:{0},姓名:{1}", key, value);        }    }}

分析:

    定义了一个有序列表实例。

    然后通过Add进行存入数据。键值对的方式存储。

    同样通过手动输入一个键名来匹配有序列表中存不存在。

    再通过if语句进行判断输出。

    再最后通过foreach遍历输出。

        一样是DictionaryEntry类型,所以必须将键id强制转换成int类型,值数据Value强制转换成字符串类型。

    运行结果:

8053cfc85d6ae60d49ba5453f122722b.png

    从上面的执行效果可以看出,SortedList 集合中的元素是按 key 值的顺序排序的。

    而这种遍历输出的方式,跟队列的方式一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值