码迷,mamicode.com
首页 > 其他好文 > 详细

学习 各个数据结构

时间:2015-08-28 00:44:58      阅读:184      评论:0      收藏:0      [点我收藏+]

标签:

 

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

    如果存储的是值类型的话:比如 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并不适合在字典中使用。 这些类型的返回 散列代码 只映射 到值上。 如果希望用作键的数值 本身没有分布在 可能的整数范围内,把整数作为键值就不好了。

 

学习 各个数据结构

标签:

原文地址:http://www.cnblogs.com/bambomtan/p/4765139.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!