數據結構學習之棧

開篇:上次咱們學習了基本的數組結構。編程

今天,咱們來學習另外一個線性的數據結構,棧。數組

 

棧這種數據結構,無時無刻不在咱們的身邊。是種極其重要的數據結構。數據結構

因此,什麼是棧呢?(不要廢話了,快說)函數

先來看咱們生活中,好比咱們常常操做的word文檔。學習

咱們好比寫入四個字, (天氣真好)。this

咱們不想要了這句話,Ctrl+Z 回撤掉咱們所打的。你會很天然發現,消失的順序會是,好->真->氣->天。spa

 

別急。 咱們再來個例子。code

好比那咱們的函數調用,blog

計算機須要有個系統棧來記錄咱們的函數調用。接口

public void A()
{
        B();
}

public void B()
{
        C();
}

public void C()
{
        //....
}

A爲咱們的主函數,當A調用B的時候,進入B函數時,會在A函數中斷的位置把函數地址信息壓入到系統棧裏。

此時B函數又在用掉C函數,此時又會在B函數中斷的位置把函數地址信息壓入到系統棧裏。

此時C執行完後,該怎麼辦呢。此時系統棧裏會取出棧頂元素爲返回的地址,爲B,程序便正確的回到B處。

一樣的。B執行完,系統棧又會取出棧頂元素爲返回的地址,爲A,程序便正確的回到A處。

此時咱們正完成了咱們的函數調用。

如咱們的圖所示:

因此。棧(stack)又名堆棧,它是一種運算受限的線性表。其限制是僅容許在表的一端進行插入和刪除運算。

插入和刪除都在棧頂這一端操做。

包括咱們的常用編程的Ide,會自動檢查括號的匹配等等。都是基於棧的結構。

 

如今,咱們基於咱們上次的線性數組。來實現咱們的自定義棧結構。

咱們讓咱們的結構實現咱們的泛型IStack接口來實現。

分別有pop出棧,push入棧。判斷是否爲空和清空操做等。

/// <summary>
    ////// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IStack<T>
    {
        void Push(T value);
        T Pop();
        T Peek();
        bool IsEmpty();
        void Clear();
    }

    public class Stack<T> : IStack<T>
    {
        private Array<T> Data;
        public Stack(int capacity=20)
        {
            this.Data = new Array<T>(capacity);
        }

        public void Clear()
        {
            this.Data.SetEmpty();
        }

        public bool IsEmpty()
        {
            return this.Data.GetSize() == 0;
        }

        public T Peek()
        {
            return this.Data.Search(this.Data.GetSize());
        }

        public T Pop()
        {
            return this.Data.Delete(this.Data.GetSize());
        }

        public void Push(T value)
        {
            this.Data.Add(value);
        }
    }

 

因而可知。這是一個重要的數據結構。

屆時,咱們來看看leetcode上的一道典型的鏈表題目。20題

題目是這樣的。

給定一個只包括 '(',')','{','}','[',']' 的字符串,判斷字符串是否有效。

有效字符串需知足:

左括號必須用相同類型的右括號閉合。
左括號必須以正確的順序閉合。
注意空字符串可被認爲是有效字符串。

先給出代碼(C#)。

public class Solution {
    public bool IsValid(string str) {
        var stack = new Stack();
            for (int i = 0; i < str.Length; i++)
            {
                if (str[i] == '[' || str[i] == '{' || str[i] == '(')
                    stack.Push(str[i]);
                else if(str[i] == ']' || str[i] == '}' || str[i] == ')')
                {
                    if (stack.Count == 0)
                        return false;
                    var top = (char)stack.Pop();
                    if (str[i] == ')' && top != '(')
                        return false;
                    if (str[i] == ']' && top != '[')
                        return false;
                    if (str[i] == '}' && top != '{')
                        return false;
                }
            }
            return stack.Count==0;
    }
}
使用的Stack類爲咱們的C#自己爲咱們提供的棧結構。本題目是 [,(,,{ 三種括號的匹配。咱們判斷。若是是這三種,咱們就相應的入棧。當遇到他們所匹配的結尾括號時,],),}時候。便相應的出棧。若是不是他們對應的標籤。即是不符合要求的。當一一遍歷出棧後。若是棧爲空時。便說明即是符合要求的。今天咱們的棧就到這裏啦,下一次,咱們來實現另外一種線性結構,隊列。
相關文章
相關標籤/搜索