学习 各个数据结构

 数组: 数组 ,他可以存储相同类型的固定数量的数据,可以通过索引取得相应的值。

    如果存储的是值类型的话:比如 int[] arr=new int[2];  那么变量arr 在栈上 ,他引用 两个 托管堆上的 int 值。

    如果存储的是引用类型:比如 Person[] arr=new Person[2]; 那么 变量 arr、在栈上,这个变量引用了 用来存储 托管堆上person类的引用的数组。

Array 类: 是一个抽象类,他实现了 ICloneable, IList, ICollection, IEnumerable 这几个接口

拷贝:

而ICloneable 实现了Clone()  他是创建一个浅表层的副本: 如果是 值类型,他复制的东西是 所有的值。 如果是应用类型,它复制的是 引用,新的数组操作的 还是 同一个内存。

    Copy 同样是浅拷贝,区别就是:Clone 直接创建一个新的数组,Copy 要有相同维数 , 和足够多的容量 存储拷贝。

需要深拷贝 引用类型数组的话, 要迭代 数组创建新的对象。

排序: Array 类使用 快排算法 对数组中的元素进行排序, Sort()方法要求 数组中的元素实现IComparable接口 。Array.Sort(strings),简单类型String int32 实现了这个借口。

IComparable接口一个 CompareTo() ,要使用sort() 要实现它,相等返回 0 , 如果 实例排在参数 前面 方法返回小于0的数, 实例排在参数后面 返回大于 0 的参数。 如果 要实现别的排序方式 可以实现 IComPare接口 ,和或 Icompare<T> 接口, IcomPare类独立于 要比较的类 这样就可以通过 Array.Sort(persons,new PersonCompare)进行比较了.

IEunmerator 接口:  枚举接口,GetEnumerator()方法 ,返回一个实现 IEunmerator 接口的的 枚举,他定义了了

bool MoveNext();
object Current { get; }
void Reset();

三个方法。

foreach 使用了  枚举

而使用 yield 迭代 会方便创建 枚举器,

public class Gge
{//实现
GetEnumerator()
public IEnumerator<String> GetEnumerator()
   {
        yield return 9;
        yield return 6;
   }
}    

就可以使用foreach 迭代 Gge了。

包含 yield 语句的 方法 或 属性 称为 迭代块 必须返回 IEnumerator、或Ienumerable 接口 ,编译时yield语句会生成一个枚举器。

通过使用 yield 定义迭代器,可在实现自定义集合类型的 IEnumerable 和IEnumerator 模式时无需其他显式类(保留枚举状态的类,有关示例,请参阅IEnumerator<T>)。

public class PowersOf2
{
    static void Main()
    {
        // Display powers of 2 up to the exponent of 8:
        foreach (int i in Power(2, 8))
        {
            Console.Write("{0} ", i);
        }
    }

    public static System.Collections.Generic.IEnumerable<int> Power(int number, int exponent)
    {
        int result = 1;

        for (int i = 0; i < exponent; i++)
        {
            result = result * number;
            yield return result;
        }
    }

    // Output: 2 4 8 16 32 64 128 256
}

  使用 迭代块 编译器会生成 一个yield 类型,其中包含一个状态机、、待完善。

集合 : 数组大小是固定的 , 如果要 要存储动态元素个数 就要使用集合。集合类 有List<T> ,队列 ,栈, 链表 ,字典 ,集。 分泛型类集合有 ArrayList HashTable.  线程安全的集合类 位于 System.Conllection.Concurrent。

动态列表有List<T > 实现了 IList , ICollection, IEnumerable , IList<T> , ICollection<T>、IEnumerable<T>,而 ArrayList是 一个非泛型 列表。  List<T> 默认 构造 一个空列表 ,添加元素后 会构建 4个元素,如过超过了的话 容量会 ,扩展倒两倍。如果容量改变 ,内容就会重新分配到新的内存中。创建新的数组,通过Array.Copy(). 所以事先知道他的 容量的话,给定容量 ,效率会更高。

有 初始值设定 ,添加元素 ,插入元素,访问元素,删除元素,收索,排序,类型转换,只读集合。

队列:队列 先进先出,Queue<T> 实现了 ICollection 和 IEnumerable <T> 接口  没有实现 IConllection<T> 接口,add remove 方法不能用于队列。 也没有实现IList<T>接口,不能用索引器访问队列。内部用 T[] 实现。待续

栈 :  先进 后出的结构,在foreach 方法中 ,IEnumerable接口迭代所有元素,栈的枚举器不会删除元素。

链表: 带续

字典: 字典是个很复杂的数据结构,它能根据键,快速查找值。也可以自由添加 和 删除元素。 有点像List<T>,但没有内存中移动后续元素的性能 开销。

作为字典中键的类型必须重写Object类的 GetHashCode() 方法,因为字典要确定元素的位置,他要调用GetHashCode() 返回的int来计算在对应位置放置的元素索引。它涉及素数,字典的容量是一个素数。 字典的新能取决于GetHashCode()的代码。

键类型还需要重写IEquatable<T>.Equals()方法。或重写Object的Equals() 方法。 如果A.Equals(B)返回true ,则 A.GetHashCode() 和 B.GetHashCode(); 如果设计出的某种重写这些方法的方式不满足 这个条件,而把它作为键的话,就会出现索引不到值的现象。

Equals方法 比较的是引用,,GetHashCode()返回的是一个仅基于对象地址的散列代码。如果 散列表基于一个键 ,而建没有重写这些方法,这个散列表就能 正常工作。 但是这么做 只有 对象完全相同,键才被认为是相等的。

String实现了IEquatable 接口,并重载了 GetHashCode() 方法,Equals()提供了值的比较,GEtHashCode() 根据字符串的值返回一个散列表代码。 字典中用字符串作为 键值很方便。

int32并不适合在字典中使用。 这些类型的返回 散列代码 只映射 到值上。 如果希望用作键的数值 本身没有分布在 可能的整数范围内,把整数作为键值就不好了。

时间: 2024-10-12 10:28:26

学习 各个数据结构的相关文章

索引学习 查找 数据结构 梳理

索引是啥? 索引是数据结构,在数据结构有一章叫查找,在国外的一本书上名字就找索引. 准确的说就是: 加快查找的数据结构. 查找的那一章: 1.有序数组的二分查找 2.二叉查找 ,在此处,为了效率防止退化,引入了平衡的调整. 3.在上述的平衡的定义,为左右高度至多差1,要求太严,调整频露高,于是红黑树应运而生,它对平衡的定义要求最长的比最短的最多2倍,降低平衡要求的目的是提高性能. 红黑树的5条性质如下: 1.节点为黑或红. 2.根和叶子为黑. 3.不能出现红红. 4,每个节点到叶子黑色高度相同.

[学习笔记]数据结构与算法

1.排序简单排序:?冒泡排序:将n个数从上往下排列,从第0个数开始依次对前n个.前n-1个.前n-2个数进行比较,保持小数在前大数在后,不符合就交换.在这个过程中,最后一个数始终是最大数.?选择排序:对所有n个.后n-1个.后n-2个依次比较,用一个变量存最小数,一趟比较完成之后,将最小数与所比较数据的第一个数进行交换.在这个过程中,第一个数始终是最小数.?插入排序:从第1个数开始向前扫描比较,小则插入.对于未排序数据,在已排序序列中向前扫描,并找到相应的位置插入.在这个过程中,整个序列局部有序

JAVA学习笔记 -- 数据结构

一.数据结构的接口 在Java中所有类的鼻祖是Object类,但是所有有关数据结构处理的鼻祖就是Collection和Iterator接口,也就是集合与遍历. 1.Collection接口 Collection c = new Xx(); // c可以称为Collection接口回调对象,虽然它被声明为Collection类型,但是实例化时实现的是接口的实现类Xx.它的方法也是用来操作实现类的对象. <span style="white-space:pre"> </s

重读《学习JavaScript数据结构与算法-第三版》-第2章 ES和TS

定场诗 八月中秋白露,路上行人凄凉: 小桥流水桂花香,日夜千思万想. 心中不得宁静,清早览罢文章, 十年寒苦在书房,方显才高志广. 前言 洛伊安妮·格罗纳女士所著的<学习JavaScript数据结构与算法>第三版于2019年的5月份再次刊印发行,新版内容契合当下,实为JavaScript开发人员的必备之佳作.有幸重读此版,与诸君分享共勉. 内容提要 此章节为第2章-ECMAScript与TypeScript概述,主要介绍了JS和TS的相关概念,以及在JS新版本中的新特性:let.解构.箭头函数

重读《学习JavaScript数据结构与算法-第三版》- 第3章 数组(一)

定场诗 大将生来胆气豪,腰横秋水雁翎刀. 风吹鼍鼓山河动,电闪旌旗日月高. 天上麒麟原有种,穴中蝼蚁岂能逃. 太平待诏归来日,朕与先生解战袍. 此处应该有掌声... 前言 读<学习JavaScript数据结构与算法>- 第3章 数组,本节将为各位小伙伴分享数组的相关知识:概念.创建方式.常见方法以及ES6数组的新功能. 数组 数组是最简单的内存数据结构,用于存储一系列同一种数据类型的值. 注:虽然数组支持存储不同类型的值,但建议遵守最佳实践. 一.数组基础 创建和初始化数组 new Array

重读《学习JavaScript数据结构与算法-第三版》- 第6章 链表(一)

定场诗 伤情最是晚凉天,憔悴厮人不堪言: 邀酒摧肠三杯醉.寻香惊梦五更寒. 钗头凤斜卿有泪,荼蘼花了我无缘: 小楼寂寞新雨月.也难如钩也难圆. 前言 本章为重读<学习JavaScript数据结构与算法>的系列文章,该章节主要讲述数据结构-链表,以及实现链表的过程和原理. 链表 链表,为什么要有这种数据结构呢?当然,事出必有因! 数组-最常用.最方便的数据结构,But,当我们从数组的起点或中间插入或移动项的成本很高,因为我们需要移动数组元素. 链表,是存储有序的元素集合.链表中的元素在内存中并不

算法入门《数据结构与算法图解》+《我的第一本算法书》+《学习JavaScript数据结构与算法第3版》

最近几年学前端的人会越来越多,再加上前端的范围越来越广,从前端发展为全栈,数据结构和算法的功底要求势必将越来越高. <数据结构与算法图解>电子书及代码是数据结构与算法的入门指南,不局限于某种特定语言,略过复杂的数学公式,用通俗易懂的方式针对编程初学者介绍数据结构与算法的基本概念,培养编程逻辑.主要内容包括:为什么要了解数据结构与算法,大O表示法及其代码优化利用,栈.队列等的合理使用,等等. <算法图解>电子书非常的体贴,看起来也很快,用图来解释算法是非常好的想法,可作为学习数据结构

python 协程库gevent学习--gevent数据结构及实战(三)

gevent学习系列第三章,前面两章分析了大量常用几个函数的源码以及实现原理.这一章重点偏向实战了,按照官方给出的gevent学习指南,我将依次分析官方给出的7个数据结构.以及给出几个相应使用他们的例子. 1.事件: 事件是一个可以让我们在Greenlet之间异步通信的形式贴上一个gevent指南上面的例子: import gevent from gevent.event import Event ''' Illustrates the use of events ''' evt = Event

Linux内核源码学习之 数据结构

本篇记录在学习Linux内核源码过程中对一些知道但不熟悉不会用的数据结构进行记录. union 是在学习进程复制函数do_fork中遇到的: <sched.h> union thread_union { struct thread_info thread_info; unsigned long stack[THREAD_SIZE/sizeof(long)]; }; struct  thread_info和stack被声明为union 共享空间 "联合"是一种特殊的类,也是一

python模块学习之数据结构--collections.counter

python包含非常多的标准数据结构,如list,tuple,dict 和set 都是内置类型.除了这些基本的内置类型.python的collections模块还很多种数据结构实现. collections----容器数据类型模块 python版本:2.6以及以后版本 collections模块包含除内置內型list,dict 和tuple之外的数据类型. 1.1 Counter 1.1.1 Counter作为一个容器(啥是容器呢,能装入不同的对象就是容器),可以跟踪相同数据的次数. 初始化输入