前言
数据结构就是相互之间存在一种或多种特定关系的数据元素的集合。 程序界有一点很经典的话,程序设计=数据结构+算法。用源代码来体现,数据结构,就是编程。
而本文则是主要介绍C#中常用的集合
Array(数组)
相信大家一开始学习的时候接触到的集合就是数组了,他也是最简单的集合。
String[] array = new String[3];
array[0] = "张三";
array[1] = "1";
array[2] = "游泳";
for(int i = 0; i < array.Length; i++)
{
Console.WriteLine(array[i]);
}
执行结果:
ArrayList
但Array还是有很多的不足,最大的不足就是需要声明长度,而ArrayList就解决了这个问题
- 他不必指定起数组的长度,他可以动态的增加素组的长度。
- 他可以存储不同的类型的数据,他会把他所有的元素都当做object来处理。
ArrayList list = new ArrayList();
list.Add("张三");
list.Add(123);
list.Add(123.2);
list.Add(true);
for(int i = 0; i < list.Count; i++)
{
Console.WriteLine(list[i]);
}
执行结果
List < T >
除了非泛型集合之外,还有泛型集合,下面是泛型集合的用法
public class Person
{
public string name;
public int age;
public string hobby;
public override string ToString()
{
return "name=" + name + ",age=" + age + ",hobby=" + hobby;
}
}
static void Main(string[] args)
{
List<Person> list = new List<Person>();
list.Add(new Person { name = "张三", age = 18, hobby = "篮球" });
list.Add(new Person { name = "李四", age = 19, hobby = "足球" });
foreach(Person p in list)
{
Console.WriteLine(p.ToString());
}
}
执行结果
LinkedList< T >
LinkedList< T >集合类没有非泛型类的版本,它是一个双向链表,它的元素指向元素的前一个与后一个元素
链表的优点是:如果要插入一个元素到链表的中间位置,会非常的快,
原因是,如果插入,只需要修改上一个元素的Next与下一个元素的Previous的引用则可。
像ArrayList列表中,如果插入,需要移动其后的所有元素。
链表的缺点是,链表只能是一个接着一个的访问,这样就要用较长的时间来查找定位位于链表中间的元素。
LinkedListNode< T >被LinkedList类包含,用LinkedListNode类,可以获得元素的上一个与下一个元素的引用。
LinkedList<int> list = new LinkedList<int>();
list.AddFirst(2);
list.AddFirst(1);
list.AddLast(4);
list.AddLast(5);
Console.Write("当前链表:\t");
foreach(int i in list)
{
Console.Write(i + "\t");
}
Console.WriteLine();
LinkedListNode<int> cur = list.Find(4); //4节点的位置
list.AddBefore(cur, 3); //在4前增加3
Console.Write("当前链表:\t");
foreach (int i in list)
{
Console.Write(i + "\t");
}
Console.WriteLine();
执行结果
HashTable
哈希表是通过key-value的形式来存取数据的
Hashtable table = new Hashtable();
table.Add("名字", "张三");
table.Add("年龄", 10);
table.Add("爱好", "游泳");
Console.WriteLine(table["名字"] + "," + table["年龄"] + "," + table["爱好"]);
执行结果
或者你想遍历Hashtable
Hashtable table = new Hashtable();
table.Add("名字", "张三");
table.Add("年龄", 10);
table.Add("爱好", "游泳");
foreach(DictionaryEntry entry in table)
{
Console.Write(entry.Key + ":");
Console.WriteLine(entry.Value);
}
执行结果
Dictionary< T >
当然还有泛型的HashTable,即Dictionary
class Person
{
public string name;
public int age;
public string hobby;
public override string ToString()
{
return "name=" + name + ",age=" + age + ",hobby=" + hobby;
}
}
class Program
{
static void Main(string[] args)
{
Dictionary<string, Person> dictionary = new Dictionary<string, Person>();
Person person1 = new Person() { name = "张三", age = 20, hobby = "游泳" };
Person person2 = new Person() { name = "李四", age = 21, hobby = "篮球" };
dictionary.Add("学生1", person1);
dictionary.Add("学生2", person2);
foreach(KeyValuePair<string, Person> pair in dictionary)
{
Console.Write(pair.Key + ":");
Console.WriteLine(pair.Value.ToString());
}
}
}
执行结果
如果只想取key的话可以这么写
foreach (string key in dictionary.Keys) //只取key
{
Console.WriteLine(key);
}
如果只想取value的话可以这么写
foreach (Person person in dictionary.Values) //只取value
{
Console.WriteLine(person);
}
HashSet< T >
HashSet的特点:一组不包含重复元素的集合。
HashSet<string> set = new HashSet<string>();
set.Add("老虎");
set.Add("狮子");
set.Add("小狗");
set.Add("小猫");
set.Add("小狗");
foreach(var n in set)
{
Console.WriteLine(n);
}
执行结果
我们发现小狗有2个,是重复值,那么HashSet就只显示一个,这就是不显示重复值的功能。
当然HashSet可以做集合运算,如UnionWith(), ExceptWith()等,这里就不再展开
Queue
队列(Queue)代表了一个先进先出的对象集合。当您需要对各项进行先进先出的访问时,则使用队列。当您在列表中添加一项,称为入队,当您从列表中移除一项时,称为出队。
Queue q = new Queue();
q.Enqueue("A");
q.Enqueue("B");
q.Enqueue("C");
Console.Write("队列中的元素:\t");
foreach(var n in q)
{
Console.Write(n + "\t");
}
Console.WriteLine();
q.Enqueue("D");
q.Enqueue("E");
Console.Write("增加后队列中的元素:\t");
foreach (var n in q)
{
Console.Write(n + "\t");
}
Console.WriteLine();
Console.Write("出队元素:");
Console.WriteLine(q.Dequeue());
执行结果:
Queue< T >
当然还有泛型队列可以使用
class Person
{
public string name;
public int age;
public string hobby;
public override string ToString()
{
return "name=" + name + ",age=" + age + ",hobby=" + hobby;
}
}
class Program
{
static void Main(string[] args)
{
Person person1 = new Person() { name = "张三", age = 20, hobby = "游泳" };
Person person2 = new Person() { name = "李四", age = 20, hobby = "篮球" };
Queue<Person> q = new Queue<Person>();
q.Enqueue(person1);
q.Enqueue(person2);
foreach(var n in q)
{
Console.WriteLine(n);
}
Console.Write("被删除的元素:");
Console.WriteLine(q.Dequeue());
}
}
执行结果
Stack
堆栈(Stack)代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时,则使用堆栈。当您在列表中添加一项,称为推入元素,当您从列表中移除一项时,称为弹出元素。
Stack st = new Stack();
st.Push("A");
st.Push("B");
st.Push("C");
st.Push("D");
Console.Write("当前栈:\t");
foreach(var n in st)
{
Console.Write(n + "\t");
}
Console.WriteLine();
st.Push("E");
st.Push("F");
Console.Write("当前栈:\t");
foreach (var n in st)
{
Console.Write(n + "\t");
}
Console.WriteLine();
Console.WriteLine("出栈的元素:" + st.Pop());
执行结果
当然栈也有泛型实现,Stack< T >,与队列类似就不再举例。