1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace StackAndQueue 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 //定义栈 14 MyStack<string> myStack = new MyStack<string>(); 15 //定义队 16 MyQueue<string> myQueue = new MyQueue<string>(); 17 18 myStack.Push("one"); 19 myStack.Push("two"); 20 myStack.Push("three"); 21 myStack.Push("four"); 22 myStack.Push("five"); 23 Console.WriteLine(myStack.Count); 24 //出five 25 Console.WriteLine(myStack.Pop()); 26 Console.WriteLine(myStack.Count); 27 //出four 28 Console.WriteLine(myStack.Pop()); 29 Console.WriteLine(myStack.Count); 30 //出three 31 Console.WriteLine(myStack.Pop()); 32 Console.WriteLine(myStack.Count); 33 //出two 34 Console.WriteLine(myStack.Pop()); 35 Console.WriteLine(myStack.Count); 36 //出one 37 Console.WriteLine(myStack.Pop()); 38 Console.WriteLine(myStack.Count); 39 //判空 40 Console.WriteLine(myStack.Pop()); 41 Console.WriteLine(myStack.Count); 42 43 //myQueue.EnQue("one"); 44 //myQueue.EnQue("two"); 45 //myQueue.EnQue("three"); 46 //myQueue.EnQue("four"); 47 //myQueue.EnQue("five"); 48 //Console.WriteLine(myQueue.Count); 49 ////出one 50 //Console.WriteLine(myQueue.DeQue()); 51 //Console.WriteLine(myQueue.Count); 52 ////出two 53 //Console.WriteLine(myQueue.DeQue()); 54 //Console.WriteLine(myQueue.Count); 55 ////出three 56 //Console.WriteLine(myQueue.DeQue()); 57 //Console.WriteLine(myQueue.Count); 58 ////出four 59 //Console.WriteLine(myQueue.DeQue()); 60 //Console.WriteLine(myQueue.Count); 61 ////出five 62 //Console.WriteLine(myQueue.DeQue()); 63 //Console.WriteLine(myQueue.Count); 64 ////判空 65 //Console.WriteLine(myQueue.DeQue()); 66 //Console.WriteLine(myQueue.Count); 67 68 } 69 70 //结点类 71 public class Node<T> 72 { 73 public T data; 74 public Node<T> next; 75 76 public T Data 77 { 78 get 79 { 80 return data; 81 } 82 set 83 { 84 data = value; 85 } 86 } 87 88 public Node<T> Next 89 { 90 get 91 { 92 return next; 93 } 94 set 95 { 96 next = value; 97 } 98 } 99 100 public Node(T data) 101 { 102 this.data = data; 103 next = null; 104 } 105 } 106 107 // 抽象一个简单父类 108 // 为栈和队列提取一些通用的成员,抽象出一个父类,此处用接口还是抽象函数? 109 // 在C#中Stack和Queue继承自两个接口:IEnumerable<T>, ICollection。 110 // 但是作为简单的实现(特别是作为面试题答案),还是写成抽象类比较好,原因有二: 111 // 1. 可以在抽象类中实现一些通用方法,子类只需要继承就可以直接用,可以简化代码。 112 // 2. 抽象出来的父类,和子类Stack、Queue可以看做“is-a”的关系。 113 // 当然也可以是非抽象的普通类,但是处于“不能实例化”的考虑,应该是抽象的 114 public abstract class AbstrackList<T> 115 { 116 //当前节点个数 117 protected int count; 118 119 //头节点,其后才是第一个节点 120 //应该为proteced,对外不可见 121 protected Node<T> Head { get; set; } 122 123 //尾节点,即最后一个节点 124 protected Node<T> Tail { get; set; } 125 126 //当前节点个数,只读 127 public int Count 128 { 129 get 130 { 131 return count; 132 } 133 } 134 135 //构造函数,初始化头节点和节点个数 136 protected AbstrackList() 137 { 138 Head = new Node<T>(default(T)); 139 Tail = Head; 140 count = 0; 141 } 142 143 //判空 144 public bool IsEmpty() 145 { 146 return count == 0 ? true : false; 147 } 148 149 //“出”的操作,对于栈和队是一样的,可以卸载父类里 150 //tip:应该从“头”出 151 //“头”出:时间复杂度为O(1); 152 //“尾”出:时间复杂度为O(n); 153 protected T Out() 154 { 155 //判空 156 if (Head.Next == null || count == 0) 157 { 158 Console.WriteLine("Is empty!"); 159 return default(T); 160 } 161 Node<T> outNode = Head.Next; 162 Head.Next = outNode.Next; 163 count--; 164 return outNode.Data; 165 } 166 167 //对于“入”的操作,栈和队是有区别的,所以定义抽象方法 168 protected abstract void In(T nodeData); 169 } 170 171 //实现栈 172 public class MyStack<T> : AbstrackList<T> 173 { 174 //实现“入栈”的方法 175 protected override void In(T nodeData) 176 { 177 Node<T> node = new Node<T>(nodeData); 178 node.Next = Head.Next; 179 Head.Next = node; 180 count++; 181 } 182 183 //入栈 184 public void Push(T nodeData) 185 { 186 In(nodeData); 187 } 188 189 //出栈 190 public T Pop() 191 { 192 return Out(); 193 } 194 } 195 196 //实现队 197 public class MyQueue<T> : AbstrackList<T> 198 { 199 //实现“入队”的方法 200 protected override void In(T nodeData) 201 { 202 Node<T> node = new Node<T>(nodeData); 203 Tail.Next = node; 204 Tail = node; 205 count++; 206 } 207 208 //入队 209 public void EnQue(T nodeData) 210 { 211 In(nodeData); 212 } 213 214 //出队 215 public T DeQue() 216 { 217 return Out(); 218 } 219 } 220 } 221 }