C#进阶学习(一)简单数据结构类之ArrayList、Stack、Queue、Hashtable

目录

前言

一、ArrayList(动态数组)

二、Stack(栈)

三、Queue(队列)

四、Hashtable(哈希表)

数据结构核心属性

常见API汇总表格

前言

在C#开发中,合理使用数据结构能显著提升程序性能和代码可维护性。本文将带你探索四个经典的非泛型集合类:ArrayListStackQueueHashtable,这些类型虽然已被泛型集合取代,但理解它们的设计思想仍是进阶学习的重要基石。

一、ArrayList(动态数组)

ArrayList是一个C#为我们封装好的类
本质是一个object类型的数组
ArrayList类帮助我们实现了很多方法
比如数组的增删查改

特点:

动态扩容:自动扩展容量(初始容量4,每次翻倍)

异构存储:可混合存储任意类型对象,就是里面啥都能存,存的是object基类对象

索引访问:支持类似数组的索引器操作

增删查改操作:

cs 复制代码
ArrayList shoppingList = new ArrayList();

// ======== 增 ========
shoppingList.Add("牛奶");    // 追加元素到末尾
shoppingList.Add(3);         // 支持不同类型存储
shoppingList.Insert(1, "面包"); // 在索引1位置插入元素

// ======== 查 ========
Console.WriteLine("第一个商品:" + shoppingList[0]); // 通过索引访问
Console.WriteLine("包含牛奶吗?" + shoppingList.Contains("牛奶")); // 元素存在性检查

// ======== 改 ========
shoppingList[2] = 5; // 通过索引直接修改元素

// ======== 删 ========
shoppingList.RemoveAt(0);     // 删除指定索引元素
shoppingList.Remove(5);       // 删除首个匹配元素

// 遍历集合
foreach (var item in shoppingList)
{
//这里迭代器遍历 别也可以使用普通的for循环遍历,因为前面说了,这其实就是一个很方便的数组
    Console.WriteLine("剩余商品:" + item);
}

注意:需要引用命名空间using System.Collections;

你也可以直接将一整个数组加进去,不过加进去加的是数组里面的元素。

二、Stack(栈)

Stack是一个C#为我们封装好的类
本质也是一个object[]数组,只是封装了特4殊的存储规则

Stack是队列存储容器
先进后出

核心方法:

  • 核心方法

    • Push():元素入栈

    • Pop():获取并移除栈顶元素

    • Peek():查看栈顶元素

代码示例:

你装入的是什么类型,弹出的就是什么类型。那么这种就必须你自己知道装入的是什么,非常不方便,后面我们会学习泛型,那个时候你就会发现没有泛型该多痛苦。

cs 复制代码
Stack browserHistory = new Stack();

// ======== 增 ========
browserHistory.Push("首页");    // 元素压入栈顶
browserHistory.Push("商品页");
browserHistory.Push("购物车");

// ======== 查 ========
Console.WriteLine("当前页面:" + browserHistory.Peek()); // 查看栈顶元素(不移除)

// ======== 删 ========
var currentPage = browserHistory.Pop();  // 弹出并返回栈顶元素
Console.WriteLine("离开页面:" + currentPage);

/* 
注意:栈结构不支持直接修改中间元素
所有操作只能在栈顶进行
*/

注意:

需要使用System.Collections命名空间

三、Queue(队列)

Quene是一个C#为我们封装好的类
本质也是一个object[]数组,只是封装了特殊的存储规则

Quene是队列存储容器
先进先出

代码示例:

cs 复制代码
Queue printerQueue = new Queue();

// ======== 增 ========
printerQueue.Enqueue("简历.pdf");  // 元素加入队尾
printerQueue.Enqueue("报告.doc");
printerQueue.Enqueue("照片.jpg");

// ======== 查 ========
Console.WriteLine("下一个文件:" + printerQueue.Peek()); // 查看队首元素(不移除)

// ======== 删 ========
while(printerQueue.Count > 0)
{
    var file = printerQueue.Dequeue();  // 移除并返回队首元素
    Console.WriteLine("正在打印:" + file);
}

/*
注意:队列结构不支持直接修改中间元素
遵循先进先出原则操作
*/

注意:

需要使用System.Collections命名空间

四、Hashtable(哈希表)

Hashtable又称散列表 是基于键的哈希代码组织起来的 键/值对集合
它的主要作用是提高数据查询的效率
使用键来访问集合中的元素

代码示例:

cs 复制代码
Hashtable countryCodes = new Hashtable();

// ======== 增 ========
countryCodes.Add("CN", "中国");  // 添加键值对
countryCodes["US"] = "美国";     // 通过索引器添加
countryCodes["JP"] = "日本";

// ======== 查 ========
if(countryCodes.ContainsKey("CN"))  // 检查键是否存在
{
    Console.WriteLine("CN对应:" + countryCodes["CN"]); // 通过键查找值
}

// ======== 改 ========
countryCodes["US"] = "美利坚合众国";  // 通过索引器修改值

// ======== 删 ========
countryCodes.Remove("JP");  // 根据键删除条目

// 遍历键值对
foreach(DictionaryEntry entry in countryCodes)
{
    Console.WriteLine($"键:{entry.Key},值:{entry.Value}");
}

注意:

需要引用命名空间:using System.Collections;

总结:

数据结构核心属性

数据结构 关键属性 说明
ArrayList Count 当前实际存储的元素数量
Capacity 当前分配的存储容量(当Count超过时自动扩容)
Stack Count 栈中元素个数
Queue Count 队列中元素个数
Hashtable Count 键值对数量
Keys 包含所有键的ICollection集合
Values 包含所有值的ICollection集合

常见API汇总表格

数据结构 方法名 功能描述
ArrayList Add(object value) 添加元素到列表末尾
Insert(int index, object value) 在指定位置插入元素
Remove(object obj) 删除第一个匹配元素
RemoveAt(int index) 删除指定索引元素
Contains(object obj) 检查元素是否存在
Stack Push(object obj) 元素压入栈顶
Pop() 移除并返回栈顶元素
Peek() 查看栈顶元素(不移除)
Queue Enqueue(object obj) 元素加入队尾
Dequeue() 移除并返回队首元素
Peek() 查看队首元素(不移除)
Hashtable Add(object key, object value) 添加键值对
Remove(object key) 根据键删除条目
ContainsKey(object key) 检查键是否存在
ContainsValue(object value) 检查值是否存在

ArrayList与普通数组的本质区别

普通数组 是固定大小的连续内存空间,在声明时必须指定长度且不可更改。它支持快速随机访问,但缺乏动态调整能力,且只能存储单一类型元素(在C#中是类型安全的)。ArrayList本质上是一个动态包装的Object数组,通过以下特性突破普通数组的限制:

  1. 动态扩容:当元素数量超过当前容量时,自动创建新数组并复制元素(默认扩容策略:容量翻倍)

  2. 类型混合:由于存储Object类型元素,可以混合存放不同数据类型

  3. 丰富操作:提供插入、删除、搜索等内置方法,无需手动实现

  4. 容量管理 :通过Capacity属性显式控制底层数组大小,平衡性能与内存

代价是:

  • 值类型存储时会产生装箱拆箱开销

  • 读取元素时需要强制类型转换

  • 自动扩容时存在内存复制消耗

相关推荐
Y.O.U..20 分钟前
力扣HOT100——无重复字符的最长子字符串
数据结构·c++·算法·leetcode
Hanson Huang6 小时前
【数据结构】堆排序详细图解
java·数据结构·排序算法·堆排序
Susea&6 小时前
数据结构初阶:队列
c语言·开发语言·数据结构
电商api接口开发6 小时前
如何在C#中使用LINQ对数据库进行查询操作?
数据库·c#·linq
搬砖工程师Cola6 小时前
<C#>在 .NET 开发中,依赖注入, 注册一个接口的多个实现
开发语言·c#·.net
序属秋秋秋6 小时前
算法基础_数据结构【单链表 + 双链表 + 栈 + 队列 + 单调栈 + 单调队列】
c语言·数据结构·c++·算法
CarnivoreRabbit8 小时前
Beamer-LaTeX学习(教程批注版)【2】
学习·latex·beamer
凡人的AI工具箱8 小时前
PyTorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(三)
人工智能·pytorch·python·深度学习·学习·生成对抗网络
purrrew8 小时前
【数据结构_5】链表(模拟实现以及leetcode上链表相关的题目)
数据结构·leetcode·链表
挺6的还9 小时前
4.B-树
数据结构·b树