C#資料結構與演算法系列(八):棧(Stack)

IT技術派發表於2020-06-18

1.介紹

棧是一個先入後出(FILO-First In Last Out)的有序列表

棧是限制線性表中元素的插入和刪除只能線上性表的同一端進行的特殊線性表。允許插入和刪除的一端,為變化的一端,稱為棧頂(Top),另一端為固定的一端,稱為棧底(Bottom)

根據棧的定義可知,最先放入棧中的元素在棧底,最後放入的元素在棧頂,而刪除元素剛好相反,最後放入的元素最先刪除,最先放入的元素最後刪除

2.圖解

 

 3.應用場景

子程式的呼叫:在跳往子程式前,會先將下一個指令的地址存入堆疊中,直到子程式執行完後再將地址取出,以回到原來的程式中

處理遞迴呼叫:和子程式的呼叫類似,只是出了儲存下一個指令的地址外,也將引數、區域變數等資料存入堆疊中

表示式的轉換【中綴表示式轉字尾表示式】與求值

二叉樹的遍歷

圖形的深度優先(depth-first)搜尋法

4.示例

用陣列模擬棧的使用,由於棧是一種有序列表,當然可以使用陣列的結構來儲存棧的資料內容,下面我們就用陣列模擬棧的出棧,入棧等操作。

示意圖

 

 程式碼實現

  public class ArrayStack
    {
        private int _maxSize;
        private int[] _arr;
        private int _top = -1;

        public ArrayStack(int maxSize)
        {
            _maxSize = maxSize;
            _arr = new int[_maxSize];
        }

        public bool IsEmpty() => _top == -1;

        public bool IsFull() => _top == _maxSize-1;

        public void Push(int value)
        {
            if (IsFull())
            {
                Console.WriteLine("棧滿");
            }
            else
            {
                _top++;
                _arr[_top] = value;
            }
        }

        public int Pop()
        {
            if (IsEmpty())
            {
                throw new Exception("棧空");
            }
            int value = _arr[_top];

            _top--;

            return value;
        }

        public void List()
        {
            if (IsEmpty())
            {
                Console.WriteLine("棧空");
            }
            else
            {
                for (int i = _top; i >= 0; i--)
                {
                    Console.WriteLine($"stack:[{i}]={_arr[i]}");
                }
            }
        }

        public static void Test()
        {
            Console.WriteLine("棧測試\n");

            bool loop = true;

            ArrayStack stack = new ArrayStack(5);

            while (loop)
            {
                Console.WriteLine("show:顯示棧");
                Console.WriteLine("exit:退出程式");
                Console.WriteLine("push:入棧");
                Console.WriteLine("pop:出棧");

                string key = Console.ReadLine();
                switch (key)
                {
                    case "show":
                        stack.List();
                        break;
                    case "exit":
                        Console.WriteLine("退出程式");
                        loop = false;
                        break;
                    case "push":
                        Console.WriteLine("請輸入一個數");
                        int value = int.Parse(Console.ReadLine());
                        stack.Push(value);
                        break;
                    case "pop":
                        try
                        {
                            int res=stack.Pop();
                            Console.WriteLine($"stack:{res}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

效果圖

 

相關文章