C#_数据结构--数据表(顺序表,链表,栈,队列)

时间:2022-06-17 10:25:56

 

常见的线性表:

     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

      用于信息持久化存储