常见的线性表:
1.顺序表 List<> 表中元素有索引和固定连续的顺序, 方便元素遍历和查找
2.链表 需要自己构建, 有固定的链接,没有索引 方便元素插入和删除
3.栈 Stack<T> 类似于一个桶,后进入的元素先出去 FILO
4.队列 Queue<> 类似于一个通道,先进入的元素先出去 FIFO
5.字典 Dictionary<> 键值对组合 键是唯一的 值与键一一对应 Key-->Value
一. 顺序表的数据结构 (代码实现) 1 class MySeqList<T>
2 { 3 private T[] _Ts; // 顺序表基于一个数组
4 private int _flag; //实际存在的成员个数 5
6
7 //构造函数 给封装变量赋予初始值
8 public MySeqList(int Max) 9 { 10 _Ts = new T[Max]; //定义顺序表容量
11 _flag = 0; 12 } 13 //构造函数 重载
14 public MySeqList() 15 { 16 _Ts = new T[10]; 17 _flag = 0; 18 } 19
20 //得到顺序表实有长度
21 public int Count() 22 { 23 return _flag; 24 } 25
26
27 //从表尾加入元素
28 public void Add(T Item) { 29 if (_flag>=_Ts.Length) 30 { 31 Console.WriteLine("out of length"); 32 return; 33 } 34 _Ts[_flag] = Item; 35 _flag++; 36 } 37
38 //删除元素
39 public int Remove(T Item) { 40 int returnValue = -1; 41 for (int i = 0; i < _flag; i++) 42 { 43 if (_Ts[i].Equals(Item)) 44 { 45 returnValue = i; 46 RemoveAt(i); 47 break; 48 } 49 } 50 return returnValue; 51 } 52
53
54 //按照索引号删除对应元素
55 public void RemoveAt(int Index) 56 { 57 if (Index<0||Index>=_flag) 58 { 59 Console.WriteLine("out of range"); 60 } 61 for (int i = Index; i < _flag; i++) 62 { 63 _Ts[i] = _Ts[i + 1]; 64 } 65 _flag--; 66
67 } 68
69
70 //找到对应元素的索引号
71 public int IndexOf(T Item) { 72 for (int i = 0; i < _flag; i++) 73 { 74 if (_Ts[i].Equals(Item)) 75 { 76 return i; 77 } 78 } 79 return -1; 80 } 81
82
83 //按索引号插入元素到指定位置
84 public void Insert(int Index,T Item) { 85 if (Index>_flag) 86 { 87 Console.WriteLine("out of range"); 88 return; 89 } 90 if (_flag>=_Ts.Length) 91 { 92 Console.WriteLine("out of length"); 93 return; 94 } 95 for (int i = _flag; i >Index; i--) 96 { 97 _Ts[i] = _Ts[i - 1]; 98 } 99 _Ts[Index] = Item; 100 _flag++; 101 } 102
103
104 //展示所有元素
105 public void ShowItem(Action<T> act) { 106 for (int i = 0; i < _flag; i++) 107 { 108 act(_Ts[i]); 109 // Console.WriteLine(_Ts[i]); 110 //当类型为system库中已经规定的类型(如 int,string等)时,可以启用 否则需使用委托
111 } 112 }
1 //翻转 (倒置)
2 public void Reverse() { 3 for (int i = 0; i < _flag/2; i++) 4 { 5 T temp=_Ts[i]; 6 _Ts[i]=_Ts[_flag-i-1]; 7 _Ts[_flag - i - 1] = temp; 8 } 9 }
113 }
二. 链表 (代码实现)
首先需要定义一个Node类,去作为链表的单个节点元素
1 public class Node<T>
2 { 3 public T Data; //节点的值
4 public Node<T> Next; //节点的下一个节点地址
5 public Node() { 6 Data=default(T); 7 Next = null; 8 } 9 public Node(T data) 10 { 11 Data = data; 12 Next = null; 13 } 14 }
然后去写链表的结构
1 class LinkList<T> 2 { 3 private Node<T> _head; // 定义一个Node类型 作为链表的引出项 4 private int _count; //表中元素个数 5 6 //构造函数 7 public LinkList() { 8 _count = 0; 9 _head = new Node<T>(); 10 } 11 12 //获取长度 13 public int length() { 14 return _count; 15 } 16 17 //添加节点 18 public void Addnode(Node<T> newNode) { 19 Node<T> temp = _head; 20 while (temp.Next!=null) 21 { 22 temp = temp.Next; 23 } 24 temp.Next = newNode; 25 _count++; 26 } 27 28 //插入节点 29 public void Insert(int index,Node<T> newNode) { 30 if (index<0||index>_count) 31 { 32 Console.WriteLine("Can not do this method"); 33 } 34 Node<T> temp = _head; 35 for (int i = 0; i < index; i++) 36 { 37 temp = temp.Next; 38 } 39 newNode.Next = temp.Next; 40 temp.Next = newNode; 41 _count++; 42 } 43 44 //查找元素位置 45 public int IndexOf(Node<T> Item) 46 { 47 Node<T> temp = _head; 48 for (int i = 0; i < _count; i++) 49 { 50 temp = temp.Next; 51 if (temp.Data.Equals(Item.Data)) 52 { 53 return i; 54 } 55 } 56 return -1; 57 } 58 59 60 //按索引移除节点 61 public T RemoveAt(int index) { 62 63 if (index<0||index>=_count) 64 { 65 Console.WriteLine("out of range"); 66 return default(T); 67 } 68 Node<T> temp = _head; 69 for (int i = 0; i < index; i++) 70 { 71 temp = temp.Next; 72 } 73 Node<T> getNode = temp.Next; 74 temp.Next = temp.Next.Next; 75 getNode.Next = null; 76 _count++; 77 return getNode.Data; 78 } 79 80 81 //展示所有元素 82 public void ShowItem(Action<T> act) { 83 if (_count==0) 84 { 85 Console.WriteLine("empty!"); 86 return; 87 } 88 Node<T> temp=_head; 89 for (int i = 0; i < _count; i++) 90 { 91 temp = temp.Next; 92 act(temp.Data); 93 } 94 } 95 96 //展示所有元素 重载 97 public void ShowItem() 98 { 99 if (_count == 0) 100 { 101 Console.WriteLine("empty!"); 102 return; 103 } 104 Node<T> temp = _head; 105 for (int i = 0; i < _count; i++) 106 { 107 temp = temp.Next; 108 Console.WriteLine(temp.Data); 109 } 110 }
拓展操作 :
1 //根据节点数据删除元素
2 public int Romove(Node<T> Item) 3 { 4 int index = -1; 5 Node<T> temp = _head; 6
7 for (int i = 0; i < _count; i++) 8 { 9 temp = temp.Next; 10 if (temp.Data.Equals(Item.Data)) 11 { 12 RemoveAt(i); 13 return index = i; 14 } 15 } 16 return index; 17 } 18
19 //数据类型为<T>的情况 移除最小值 注:只有数值类型可以进行此操作 如int,float,double.....
20 public T RemoveMin(Func<Node<T>, Node<T>, bool> _func) 21 { 22 Node<T> delPreMin, delMin, preMin, Min; 23 delMin = Min = _head.Next; 24 delPreMin = preMin = _head; 25 while (Min!=null) 26 { 27 if (_func(delMin,Min)) 28 { 29 delMin = Min; 30 delPreMin = preMin; 31
32 break; 33 } 34 Min = Min.Next; 35 preMin = preMin.Next; 36 } 37 delPreMin.Next = delPreMin.Next.Next; 38 delMin.Next = null; 39 _count--; 40 return delMin.Data; 41 } 42
43 //颠倒元素
44 public void Reverse() { 45 Node<T> temA,temB; 46 temB = _head.Next; 47 _head.Next = null; 48 while (temB!=null) 49 { 50 temA = temB.Next; 51 temB.Next = _head.Next; 52 _head.Next = temB; 53 temB = temA; 54 } 55 }
}
三. 栈和队列都是受限的线性表
栈常用的方法:
Stack<type> sta=new Stack<type>(); 定义一个栈
sta .pop 出栈(移除并返回栈顶元素)
sat .push 进栈,压栈
sat .peek 获取栈顶元素,但不将其移除
sta.ToArray 转化为数组( type[] Its=sta.toArray(); 注意 Its[0]为栈顶元素,栈顺序为先进后出 )
队列常用方法:
Queue<type> que=new Queue<type>(); 定义一个队列
que.Dequeue 出队(移除并返回队首元素)
que.Enqueue 入队
que.Peek 获取队首元素(不移除)
que.ToArray 转化为数组 ( type[] Its=que.toArray(); 注意 Its[0]为队首元素,队列顺序为先进先出 )
四.字典
key;Value
用于信息持久化存储