[算法]栈

一、栈的定义

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();
        }
    }
View Code

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();
        }
    }
View Code

三、栈的应用

原文地址:https://www.cnblogs.com/hbq-fczzw/p/3347333.html