大話數據結構-棧與隊列


文章知識點來至於大話數據結構里邊章節知識, 這篇主要介紹棧與隊列在計算機中存儲形式, 以及在某些算法領域中對棧和隊列的相關應用。章節最后介紹了著名的逆波蘭表達式, 以及通過算法來實現該表達式的運算過程。 在實現代碼的同時添加了流程圖。相關代碼源碼請查看文章最后。

棧與隊列

1 棧結構定義

                                

2 棧的順序存儲

 

3 兩棧共享空間

         思路:他們是在數組的兩端,向中間靠攏top1和top2是兩個棧的棧頂指針, 只要兩個指針不碰頭就可以

         圖解

 

4 棧的鏈式存儲

        

5 棧的順序存儲和鏈式存儲區別

         如果棧使用過程中元素變化不可預測, 有時候小, 有時候非常大, 那么推薦用棧的鏈式存儲。 如果一直棧的的元素變化在可控范圍內, 推薦使用棧的順序存儲。

6 后綴表達式

         表達式:9 3 1 – 3 * + 10 2 / +

         規則:從左到右遍歷表達式中的每個數字和符號, 遇到是數字就進棧, 遇到事符號就就將棧頂兩個數字取出進行計算, 運算結果進棧, 一直到最終獲得結果。

5 中綴表達式轉后綴表達式

         中綴表達式“9+(3-1)*3+10/2”轉化為后綴表達式“9 3 1 3 – 3 * + 10 2 / +”

         規則:從左到右遍歷表達式的每個數字和符號,若是數字就輸出,就成為后綴表達式的一部分;若是符號,則判斷與其棧頂符號的優先級,是右括號或者優先級低於棧頂元素則棧頂元素以此出棧並輸出,並將當前符號進棧,一直到最終輸出后綴表達式。

6 隊列

         定義:只允許在一段進行插入操作,而在另一端進行刪除操作的線性表。隊列是一種先進先出的線性表,簡稱FIFO。允許插入的一段陳為隊尾,允許刪除的一段稱為對頭

         循環隊列

                   定義:我們把隊列頭尾相接的順序存儲結構稱為循環隊列

7 隊列的鏈式存儲

         隊列的鏈式存儲結構其實就是線性表的單鏈表,只不過它只能頭出尾進,我們把它簡稱為隊列。

8 接下來開始對以上知識點實踐運用,我們已計算器為例來說明算法對於堆棧的使用。目的是計算表達式9+(3-1)*3+10/2的運行結果

首先我們熟悉下后綴表達式9 3 1 3 – 3 * + 10 2 / +, 他是通過中綴表達式9+(3-1)*3+10/2的來的。 關於中綴表達式轉后綴表達式

   中綴表達式“9+(3-1)*3+10/2”轉化為后綴表達式“9 3 1 3 – 3 * + 10 2 / +”

         規則:從左到右遍歷表達式的每個數字和符號,若是數字就輸出,就成為后綴表達式的一部分;若是符號,則判斷與其棧頂符號的優先級,是右括號或者優先級低於棧頂元素則棧頂元素以此出棧並輸出,並將當前符號進棧,一直到最終輸出后綴表達式。

關於后綴表達式計算:

    表達式:9 3 1 – 3 * + 10 2 / +

         規則:從左到右遍歷表達式中的每個數字和符號, 遇到是數字就進棧, 遇到事符號就就將棧頂兩個數字取出進行計算, 運算結果進棧, 一直到最終獲得結果。

9 中綴表達式轉后綴表達式流程圖:

后綴表達式計算結果流程圖:

10 中綴表達式轉后綴表達式實現代碼:

public static string GetSufficExpression(string expression)
        {
            var expressionArray = expression.Split(' ');
            var operateStack = new StackLinkList();
            var sufficExpression = string.Empty;
            for (var i = 0; i < expressionArray.Length; i++)
            {
                var input = expressionArray[i];
                if (string.IsNullOrEmpty(input))
                {
                    continue;
                }
                if (IsNumber(input))
                {
                    sufficExpression += string.Format("{0} ", input);
                    continue;
                }
                else if (input == ")")
                {
                    while (true)
                    {
                        var popValue = operateStack.Pop();
                        if (popValue == "(")
                        {
                            break;
                        }
                        sufficExpression += string.Format("{0} ", popValue);
                    }
                }
                else if (IsOperationChar(input))
                {
                    while (true)
                    {
                        if (operateStack.IsEmpty())
                        {
                            operateStack.Push(input);
                            break;
                        }
                        var popValue = operateStack.Pop();
                        if (!IsOperationChar(popValue))
                        {
                            operateStack.Push(popValue);
                            operateStack.Push(input);
                            break;
                        }
                        if (ComparePriority(input, popValue) <= 0)
                        {
                            sufficExpression += string.Format("{0} ", popValue);
                        }
                        else
                        {
                            operateStack.Push(popValue);
                            operateStack.Push(input);
                            break;
                        }
                    }
                }
                else
                {
                    operateStack.Push(input);
                }
            }
            while (true)
            {
                if (operateStack.IsEmpty())
                {
                    break;
                }
                sufficExpression += string.Format("{0} ", operateStack.Pop());
            }
            return sufficExpression;
        }
中綴表達式轉后綴表達式

后綴表達式計算結果代碼:

  public static string GetCalculateResult(string sufficExpression)
        {
            var operateStack = new StackLinkList();
            var expressionArray = sufficExpression.Split(' ');
            for (int i = 0; i < expressionArray.Length; i++)
            {
                var inputChar = expressionArray[i];
                if (string.IsNullOrEmpty(inputChar))
                {
                    continue;
                }
                if (!IsOperationChar(inputChar) && !IsNumber(inputChar))
                {
                    throw new ArgumentException();
                }
                if (IsNumber(inputChar))
                {
                    operateStack.Push(inputChar);
                }
                else
                {
                    int stackTopLeft;
                    int stackTopRight;
                    if (!int.TryParse(operateStack.Pop(), out stackTopRight)
                        || !int.TryParse(operateStack.Pop(), out stackTopLeft))
                    {
                        throw  new InvalidOperationException();
                    }
                    operateStack.Push(Caculator(inputChar, stackTopLeft, stackTopRight).ToString(CultureInfo.InvariantCulture));
                }
            }

            return operateStack.Pop();
        }
后綴表達式計算結果

 單元測試:

 private static void TestCaculator()
        {
            var sufficExpression = Calculator.GetSufficExpression("9 + ( 3 - 1 ) * 3 + 10 / 2");
            Assert.IsEqual(sufficExpression.Trim(' '), "9 3 1 - 3 * + 10 2 / +");
            var caculateResult = Calculator.GetCalculateResult(sufficExpression);
            Assert.IsEqual(caculateResult, "20");

            var sufficExpression1 = Calculator.GetSufficExpression("9 + ( 3 - 1 )");
            Assert.IsEqual(sufficExpression1.Trim(' '), "9 3 1 - +");
            var caculateResult1 = Calculator.GetCalculateResult(sufficExpression1);
            Assert.IsEqual(caculateResult1, "11");

            var sufficExpression2 = Calculator.GetSufficExpression("9 + ( 3 - 1 ) * 2 + 8 / 2 * 3");
            Assert.IsEqual(sufficExpression2.Trim(' '), "9 3 1 - 2 * + 8 2 / 3 * +");
            var caculateResult2 = Calculator.GetCalculateResult(sufficExpression2);
            Assert.IsEqual(caculateResult2, "25");
        }
單元測試

最后附上源代碼下載地址:

http://download.csdn.net/detail/w_wanglei/5689883


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM