zoukankan      html  css  js  c++  java
  • [算法]栈

    一、栈的定义

    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

    三、栈的应用

  • 相关阅读:
    flutter android 开发笔记(三.flutter和android数据交互)
    flutter android 开发笔记(二.module集成,混合页面)
    flutter android 开发笔记(一.集成)
    svn主干开辟分支、分支合并到主干
    svn主干开辟分支、分支合并到主干
    打包aar时把依赖的jar打包进aar中
    as修改已有项目的svn地址
    Flutter踩坑日记(一)
    android中两个不同名称的app不能同时安装
    aar、jar、so的引入和aar打包包含so、aar、jar文件
  • 原文地址:https://www.cnblogs.com/hbq-fczzw/p/3347333.html
Copyright © 2011-2022 走看看