一、栈的定义
1.1 概念
栈是一种特殊的线性表,一种只能在顶部进行插入和删除操作的线性表。这个限制也使得栈具有后进先出(LIFO)的特性。
1.2 特性
1)后进先出LIFO;
2)主要操作:入栈(Push)、出栈(Pop)。
1.3 API
public class Stack<T> : IEnumerable { Stack() // 构造函数 int Size() // 栈大小 Boolean IsEmpty() // 栈空判断 void Push(T item) // 入栈 T Pop() // 出栈 }
二、栈的实现
2.1 顺序存储结构
public class ArrayStack<T> : IEnumerable { /// <summary> /// 栈中存储元素的数组 /// </summary> private T[] items; /// <summary> /// 栈的大小。 /// N-1极为栈顶元素的下标,N > 1时有效 /// </summary> private int N; /// <summary> /// 构造函数,初始化数组和栈大小 /// </summary> public ArrayStack() { this.items = new T[2]; this.N = 0; } /// <summary> /// 扩大/缩小栈大小方法 /// </summary> /// <param name="capacity">重置后的栈大小</param> public void Resize(int capacity) { if (capacity < N) throw new InvalidOperationException(); T[] temp = new T[capacity]; for (int i = 0; i < N; i++) { temp[i] = items[i]; } this.items = temp; } /// <summary> /// 栈大小 /// </summary> public int Size { get { return this.N; } } /// <summary> /// 栈是否为空 /// </summary> /// <returns>true表示栈为空,否则非空</returns> public bool IsEmpty() { return N == 0; } /// <summary> /// 入栈操作 /// </summary> /// <param name="item">入栈元素</param> public void Push(T item) { this.items[N++] = item; if (N == items.Length) Resize(items.Length * 2); } /// <summary> /// 出栈操作 /// </summary> /// <returns>出栈元素</returns> public T Pop() { if (IsEmpty()) throw new InvalidOperationException(); T item = this.items[--N]; if (N == this.items.Length / 4) Resize(this.items.Length / 2); return item; } public override String ToString() { StringBuilder builder = new StringBuilder(); foreach(var i in this) { builder.AppendFormat("{0} ", i); } return builder.ToString(); } /// <summary> /// 查看当前元素 /// </summary> /// <returns></returns> public T Peek() { if (IsEmpty()) throw new InvalidOperationException(); return items[N - 1]; } IEnumerator IEnumerable.GetEnumerator() { for (int i = 0; i < N; i++) { yield return items[i]; } } static void Execute() { #region ArrayStack测试 /**================ArrayStack测试===================*/ ArrayStack<int> arrayStack = new ArrayStack<int>(); arrayStack.Push(1); arrayStack.Push(2); arrayStack.Push(3); arrayStack.Push(4); arrayStack.Push(5); Console.WriteLine("================ArrayStack测试==================="); Console.WriteLine(arrayStack.Pop()); arrayStack.Push(6); Console.WriteLine(arrayStack.Pop()); arrayStack.Push(7); Console.WriteLine(arrayStack.Pop()); Console.WriteLine(arrayStack.Pop()); arrayStack.Push(8); arrayStack.Push(9); Console.WriteLine(arrayStack.Pop()); /**=================================================*/ #endregion Console.ReadKey(); } }
2.2 链式存储结构
public class LinkNodeStack<T> : IEnumerable { /// <summary> /// 栈的大小 /// </summary> private int N; /// <summary> /// 栈顶节点 /// </summary> private Node top; public LinkNodeStack() { this.N = 0; this.top = null; Debug.Assert(IsCorrect()); } public LinkNodeStack(LinkNodeStack<T> stack) { this.N = stack.N; this.top = new Node(stack.top); } /// <summary> /// 内嵌的节点类,是一个单向链表结构 /// </summary> private class Node { public T item; public Node prev; public Node() { } public Node(Node node) { item = node.item; if (node.prev != null) { prev = new Node(node.prev); } } } /// <summary> /// 栈大小 /// </summary> public int Size { get { return N; } } /// <summary> /// 栈是否为空 /// </summary> /// <returns>true表示栈为空,否则非空</returns> public bool IsEmpty() { return N == 0; } /// <summary> /// 入栈操作 /// </summary> /// <param name="item">入栈元素</param> public void Push(T item) { Node oldTop = top; top = new Node(); top.item = item; top.prev = oldTop; N++; Debug.Assert(IsCorrect()); } /// <summary> /// 出栈操作 /// </summary> /// <returns>出栈元素</returns> public T Pop() { if (IsEmpty()) throw new InvalidOperationException(); T item = top.item; top = top.prev; N--; Debug.Assert(IsCorrect()); return item; } /// <summary> /// 查看当前栈顶元素 /// </summary> /// <returns></returns> public T Peek() { if (IsEmpty()) throw new InvalidOperationException(); return top.item; } /// <summary> /// 判断栈结构是否正确,用于断言 /// </summary> /// <returns>ture表示结构正确,反之则错误</returns> public bool IsCorrect() { if (N == 0) { if (top != null) return false; } else if (N == 1) { if (top == null) return false; if (top.prev != null) return false; } else { if (top.prev == null) return false; } return true; } public IEnumerator GetEnumerator() { Node temp = top; while (temp != null) { yield return top.item; temp = temp.prev; } } static void Execute(string[] args) { #region LinkNodeStack测试 LinkNodeStack<int> linkNodeStack = new LinkNodeStack<int>(); linkNodeStack.Push(1); linkNodeStack.Push(2); linkNodeStack.Push(3); linkNodeStack.Push(4); linkNodeStack.Push(5); Console.WriteLine("================ArrayStack测试==================="); Console.WriteLine(linkNodeStack.Pop()); linkNodeStack.Push(6); Console.WriteLine(linkNodeStack.Pop()); linkNodeStack.Push(7); Console.WriteLine(linkNodeStack.Pop()); Console.WriteLine(linkNodeStack.Pop()); linkNodeStack.Push(8); linkNodeStack.Push(9); Console.WriteLine(linkNodeStack.Pop()); #endregion Console.ReadKey(); } }
三、栈的应用