1.1 群集(collection)的定义

群集是一种结构化的数据类型。它存储数据,并且提供数据的添加、删除、更新操作,以及对群集的不同属性值的设置与返回操作。

群集可以分为两类:线性的和非线性的。

线性群集是一张元素列表,表中的元素顺次相连。线性群集中的元素通常由位置来决定次序。在现实世界中,购物清单就是很好的线性群集实例。而在计算机世界中则把数组设计成线性群集。

非线性群集所包含的元素在群集内没有位置次序之分。组织结构图就像用架子垒好的台球一样是一个非线性群集的实例。而在计算机世界中树、堆、图和集都是非线性群集。

无论是线性的还是非线性的群集都拥有一套定义好的属性和操作的集合。其中,属性用来描述群集,而操作就是群集能执行的内容。

1.2 群集(collection)的描述

有两种主要的群集类中有几个子类别。线性的群集可能是直接存取群集,也可能是顺序存取群集。而非线性的群集既可以是层次群集,也可以是组群集。

1.2.1 直接存取群集

直接存取群集最常见的实例就是数组。这里把数组定义为具有相同数据类型的元素的群集,而且所有数组元素可以通过整数型索引直接进行存取访问。

数组可以是静态的,这样当声明数组的时候便于针对程序的长度来固定指定元素的数量。数组也可以是动态的,通过ReDim或者ReDim Preserve语句就可以增加数组元素的数量。

在C#中,数组不只是内置的数据类型,它还是一种类。

可以用数组来存储一个线性的群集。向数组添加新元素是很容易的,只要简单地把新元素放置在数组尾部第一个空位上就可以了。但是,在数组中插入一个元素就是不那么容易的了。因为要给插入的元素空出位置,所以需要按顺序向后移动数组元素。.Net框架为简化线性群集的编程提供了一种专门的数组类ArrayList。

字符串是直接存取群集的另外一种类型。字符串是字符的群集。和存取数组元素的方式一样,也可以基于字符的索引对其进行存取。在C#中,字符串也是作为类的对象来实现的。这个类包含一个在字符串上执行标准操作的庞大的方法集合,其中操作有串连接、返回字串、插入字符、移除字符等。

C#字符串是不可变的。这意味着一旦对字符串进行了初始化,就不能在改变它了。当要修改字符串时,不是改变原始的字符串,而是创建一个字符串的副本。在某些情况下这种行为可能会导致性能下降,所以.Net框架提供了StringBuilder类来让用户能处理可变的字符串。

结构是最后一种直接存取的群集类型。结构是一种复合数据类型。它包含的数据可能拥有许多不同的数据类型。

虽然.Net环境中许多元素都是作为类来实现的(比如数组和字符串),但是语言的几个主要元素还是作为结构来实现的,比如数字数据类型。例如,整数类型就是作为Int32结构来实现的。采用Int32的方法之一就是把用字符串表示的数转换成为整数的Parse方法。示例如下:

static void Main(string[] args)
{
int num;
string snum;
snum = Console.ReadLine();
num = Int32.Parse(snum);
Console.WriteLine(num);
}

1.2.2 顺序存取群集

顺序存取群集是把群集元素按顺序存储的表。这里也把此类群集称为线性表。线性表在创建时没有大小限制,这就意味着它们可以动态的扩展和收缩。不能对线性表中数据项进行直接存取访问,而要像如下图所示的那样通过数据项的位置对其进行存取。线性表的第一个元素在表头的位置,而最后一个元素在表尾的位置。

由于不能直接存取线性表的元素,为了访问某个元素就需要遍历线性表直到到达要找元素的位置为止。线性表的实现通常允许两种遍历表的方法:一种是单向从前往后遍历,而另一种则是双向遍历,即从前向后和从后向前遍历。

线性表的一个简单实例就是购物清单。顺次写下要购买的全部商品就会形成一张购物清单。在购物时一旦找到某种商品就把它从清单中划掉。

线性表既可以是有序的,也可以是无序的。有序线性表具有顺次对应的有序值。如下列人名所表示的情况:Beata、Bernica、David、Frank、Mike。而无序线性表则是由无序元素组成的。

线性表的某些类型限制访问数据元素。这类线性表有堆栈和队列。堆栈是一种只允许在表头(或顶端)存取数据的表。在表的顶端放置数据项,而且也只能从表的顶端移出数据项。正是基于这种原因,堆栈也被称为后进先出结构 。这里把向堆栈添加数据项的操作称为入栈,而把从堆栈移出数据项的操作称为出栈。如图所示:

堆栈是非常常见的一种数据结构,特别是在计算机系统编程中尤为普遍。在堆栈的众多应用中,它常用于算术表达式的计算和平衡符号。

队列是一种只允许在表尾进行数据项添加和移出操作的表。它也被称为是先进先出结构。这里把向队列添加数据项称为EnQueue,而把从队列移出数据项称为DeQueue。如图所示:

最后要讨论的一类线性群集被称为通用的索引群集,这类群集的第一种就是散列表。它存储了一组与关键字相关联的数据值。在散列表中有一个被称为散列函数的特殊函数。此函数会取走一个值,并把此数据值(称为关键字)转换成用来取回数据的整数索引。然后此索引会用来存取访问与关键字相关联的数据记录。C#中HashTable类用来存储散列表的数据。

另外一种通用的索引群集就是字典。字典也被称为联合,它是由一系列键值对构成的。Dictionary

1.2.3 层次群集

非线性群集分为两大主要类型:层次群集和组群集。层次群集是一组划分了层次的数据项集合。位于某一层的数据项可能会有位于下一较低层上的后继数据项。

树是一种常见的层次群集。树群集看上去像是一棵倒立的树,其中一个数据项作为根,而其它数据项则作为叶子挂在根的下面。树的元素被称为节点,而且在特定节点下面的元素被称为是此节点的孩子。如图展示了一棵实例树:

树在几种不同的领域都有应用。大多数现代操作系统的文件系统都是采用树群集设计而成的。其中一个目录作为根,而其它子目录则作为根的孩子们。

二叉树是树集群的一种特殊类型,树中每个节点最多只有两个孩子。二叉树可以变成二叉查找树,这样做可以极大地提高查找大量数据的效率。实现的方法是依据从根到要存储数据的节点的路径为最短路径的方式来放置节点。

还有一种树类型就是堆。堆这样组织就是为了便于把最小数据值始终放置在根节点上。在删除时会移动根节点。此外,堆的插入和删除操作总是会导致堆的重组,因为只有这样才能把最小值放在根节点上。我们经常会用堆来排序,称为是堆排序。通过反复删除根节点以及重组堆的方式就可以对存储在堆内的数据元素进行排序。

1.2.4 组群集

数据项为无序的非线性群集被称为组。集合、图和网络是组群集的三种主要类型。

集合是一种无序数据值的群集,并且集合中每一个数据值都是唯一的,当然了就像整数一样,班级中学生的列表就是一个集合的实例。在集合上执行的操作包括联合和交叉。如图显示了操作集合的实例:

图是由节点集合以及与节点相连的边集合组成的。图用来对必须访问图中每个节点的情况进行建模,而且有些时候还要按照特定顺序进行访问。这样做的目的是为了找到“遍历”图的最有效的方法

网络是图的一种特殊类型网络的每一条边都被赋予了特权。权同使用某边从一个节点移动到另一个节点所花费的代价相关。

1.3 CollectionBase类

.Net框架库不包括用于存储数据的通用Collection类,但是可以使用一种抽象的类CollectionBase类来构造属于自己的Collection类。CollectionBase类为程序员提供了实现定制Collection类的能力。CollectionBase类隐含实现了两个为构造Collection类所必须的接口,即ICollection和IEnumerable,而留给程序员要做的工作就只是对这些作为Collection类特殊内容的方法的实现。

1.3.1 用ArrayList实现Collection类

1.3.2 定义Collection类

在C#中定义一个Collection类最简单的方法就是把在System.Collections库中已找到的抽象类CollectionBase类作为基础类。此类提供了一套可以实现构造构造自身群集的抽象方法集合。CollectionBase类还提供了一种基础的数据结构InnerList(一个ArrayList)。此结构可以用作自身类的基础。

1.3.3 实现Collection类

namespace test
{
class Program
{
static void Main(string[] args)
{
Collection names = new Collection();
names.Add("David");
names.Add("Bernica");
names.Add("Raymond");
names.Add("Clayton");
foreach (object name in names)
{
Console.WriteLine(name);
}
Console.WriteLine("Number of names: " + names.Count());
names.Remove("Raymond");
Console.WriteLine("Number of names: " + names.Count());
names.Clear();
Console.WriteLine("Number of names: " + names.Count());
Console.ReadKey();
}
} public class Collection : CollectionBase
{
public void Add(Object item) //ArrayList把数据作为对象(即Object数据类型)来存储
{ //这就是把数据项声明为Object的原因
InnerList.Add(item);
} public void Remove(Object item)
{
InnerList.Remove(item);
} public new void Clear()
{
InnerList.Clear();
} public new int Count() //由于是在基础类CollectionBase中实现Count
{ //所以必须用新的关键词来隐藏CollectionBase中找到的Count的定义
return InnerList.Count;
} }
}

1.4 泛型编程

面向对象编程的问题之一就是所谓“代码膨胀”的特征。为了说明方法参数所有可能的数据类型而需要重载某种方法或重载一套方法集合的时候,就会发生某种类型的代码膨胀。代码膨胀的解决方案之一就是使某个值呈现多种数据类型的能力,同时仅提供此值的一种定义。这种方法被称为是泛型编程。

泛型编程提供数据类型“占位符”。它在编译时由特定的数据类型填充。这个占位符用一对尖括号<>和放在括号之间的标识符来表示。如实例:

泛型编程第一个规范实例就是Swap函数,如:

namespace test
{
class Program
{
static void Main(string[] args)
{
int n1 = ;
int n2 = ;
Swap<int>(ref n1, ref n2); //注意调用时参数的填写
Console.WriteLine("n1: " + n1);
Console.WriteLine("n2: " + n2);
Console.ReadKey();
} static void Swap<T>(ref T val1, ref T val2)
{
T temp;
temp = val1;
val1 = val2;
val2 = temp;
} }
}

参考链接:

https://www.cnblogs.com/dotnet261010/p/9034594.html

1.5 时间测试

参考链接:

https://www.cnblogs.com/helloxyz/archive/2011/04/08/2009882.html

第1章.Collections类、泛型类和Timing类概述的更多相关文章

  1. 第一章 Collections 类、泛型类和Timing类概述

    摘抄<数据结构与算法(C#语言描述)> 删除很多废话 1.1群集(collection)的定义 群集是一种结构化的数据类型.存储数据,并且提供数据的添.删.改操作,以及对群集不同属性值的设 ...

  2. 第三章:Python高级编程-深入类和对象

    第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...

  3. System.Collections空间下的Hashtable类与System.Collections.Specialized下的StringDictionary的一点小区别

    哎.有一周没有写自己的博客. 最近在做一个调用web服务的小程序,没有使用c#自动生成的代理类,而是使用http-get.post.以及soap的方式去请求的,使用这http请求这种方式需要自己去拼参 ...

  4. [PY3]——合并多个字典或映射(collections模块中的ChainMap 类)

    问题 现在有多个字典或者映射,你想将它们从逻辑上合并为一个单一的映射后执行某些操作, 比如查找值或者检查某些键是否存在. 解决方案 使用 collections 模块中的 ChainMap 类 Cha ...

  5. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_07 Collections工具类_3_Collections集合工具类的方法

    第二个参数传递了一个匿名内部类.结果就出现了下面的代码 源码里面有Compare方法,对比两个参数 要重写比较的方法 对对象进行排序 创建学生类.对学生类进行排序 重写Person的ToString方 ...

  6. C#-ade.net-实体类、数据访问类

    实体类.数据访问类 是由封装演变而来,使对数据的访问更便捷,使用时只需要调用即可,无需再次编写代码 实体类是按照数据库表的结构封装起来的一个类 首先,新建文件夹 App_Code ,用于存放数据库类等 ...

  7. ado.net 实体类_数据访问类

    实体类: using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ...

  8. [转]掌握 ASP.NET 之路:自定义实体类简介 --自定义实体类和DataSet的比较

    转自: http://www.microsoft.com/china/msdn/library/webservices/asp.net/CustEntCls.mspx?mfr=true 发布日期 : ...

  9. EpPlus读取生成Excel帮助类+读取csv帮助类+Aspose.Cells生成Excel帮助类

    大部分功能逻辑都在,少量自定义异常类和扩展方法 ,可用类似代码自己替换 //EpPlus读取生成Excel帮助类+读取csv帮助类,epplus只支持开放的Excel文件格式:xlsx,不支持 xls ...

随机推荐

  1. 如何使用jmeter做一个功能的性能测试

    一.为什么又再次写类似的文章? 在博客园和公号写文章,已经快两年了,所以自然在公号和博客园都能联系到我的. 也就是几天前,有个人加我微信,对于总有人加我好友,我已经觉得不奇怪了,为什么呢? 加我好友的 ...

  2. vscode 调试 react 项目

    主要分为以下三个步骤 安装 debug for chrome 配置 launch.json 文件 配置内容如下 { "version": "0.2.0", &q ...

  3. yum管理及源码安装

    一.配置YUM库及更新操作 yum概述 基于RPM包构建的软件更新机制,自动解决软件依赖关系 YUM仓库格式 本地:file:// 网络:ftp://或http:// yum源里面包含的内容 .rpm ...

  4. 实验21:IPv6

    九.IPv6 1.IPv6(RIP) 实验目的:熟悉IPv6的配置,并经过动态路由协议RIP,使三台路由器相互通讯设备需求:3640三台实验过程: xdbr_R1#sh runipv6 unicast ...

  5. JavaScript 与 Java 有什么不同?

    JavaScript 编程语言是由 Netscape,Inc. 开发的,它并不是 Java 平台的一部分. JavaScript 不会创建小应用程序或独立应用程序.在最常见的形式中,JavaScrip ...

  6. symfony开发步骤简述

    对symfony具体开发也有了一定时间的接触了,下面说一下开发步骤,以备自己以后查看; 1.确定表关系,字段等 2.在相应的模块下的Rescourse下config/Doctrine创建相应的.orm ...

  7. angular 控件间的通信

    先引入 设置meta元素 http://blog.sina.com.cn/s/blog_51048da70101cgea.html //设置 虚拟窗口的大小等于设备的大小 <meta name= ...

  8. PYTHON 学习笔记2 流程控制工具以及函数定义、匿名函数

    前言 在上一节的学习中.已经介绍了几种基本类型.包括字符串的定义,以及字符串中索引.切片.字符串拼接的使用方法.以及基本的整形数据运算.一些之前都没有了解过的运算符.比如 ** 乘方 //整数除法等. ...

  9. [Python]JavaScript VS Python 函数

    js function 相当于 python def js语句结束符; python为缩进符 JavaScript /*定义*/ function 函数名(参数1,参数2,参数3...){ 函数体 } ...

  10. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.

    mongoose报错:DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and wil ...