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 }