數據結構——棧、隊列和數組

二、棧、隊列和數組

這篇總結的主要是棧和隊列的知識點,可以收藏下來,哪些地方概念不是特別清楚的時候翻出來看看。如果想看本章涉及到的代碼部分,見文章下方超鏈接。

另外有些地方序號可能排版比較亂,之前在Typora上寫的,導入過來之後貌似排序受到了影響,希望不影響閱讀。

(一)棧和隊列的基本概念
    • 棧的基本概念

      • 一種只能在一端進行插入和刪除的線性表。允許進行插入和刪除的操作的稱爲棧頂(Top),表的另一端稱爲棧底,棧底固定不變。棧的插入和刪除操作稱爲入棧出棧
      • 棧頂有一個稱爲棧頂指針的位置指示器(就是一個變量,對於順序棧,就是記錄棧頂元素所在數組位置的標號的一個整型變量,對於鏈式棧,就是記錄棧頂元素所在結點的指針,它是動態變化的)。
    • 棧的特點

      • 棧是一種在操作上稍加限制的線性表,本質還是線性表
      • 棧的主要特點就是先進後出FILO (Front In Last Out)。
    • 棧的數學性質

      • 當n個元素以某種順序入棧,並且可以在任意時刻出棧(滿足先進後出的前提),所獲得的元素排列的數目N滿足函數Catalan(),即
        N=1n+1C2nn N=\frac{1}{n+1}C^n_{2n}
    • 棧的存儲結構

      • 順序存儲結構——順序棧
      • 鏈式存儲結構——鏈式棧
    • 形象的記憶方法就是:想象着一車隊開進了死衚衕。

  1. 隊列

    • 隊列的基本概念
      • 其限制爲:僅在表的一端進行插入,另一端進行刪除。可進行插入的稱爲隊尾(Rear),可進行刪除的稱爲隊頭(Front)。向隊列中進行插入和刪除元素稱爲入隊和出隊。
    • 隊列的特點
      • 是一種先進先出FIFO(–First In First Out)的數據結構
      • 隊是一種在操作上稍加限制的線性表,本質還是線性表
    • 隊列的存儲結構
      • 順序存儲結構——順序隊
      • 鏈式存儲結構——鏈式隊
    • 形象的記憶方法就是:想象着一車隊開進了一個暢通的隧道。
(二)棧和隊列的順序存儲結構
  1. 棧的順序存儲結構

    • 棧的順序存儲又稱爲順序棧,它是利用一組地址連續的存儲單元一次性存放自棧底到棧頂的數據元素,同時設指針指示棧頂元素在順序棧的位置

    • 順序棧(st)的4個要素,包括兩個狀態和兩個操作(下面爲一般操作)

      • 棧空狀態

        st.top = -1;					//這裏表示棧頂元素的數組下標,-1爲不存在,代表棧內無結點
        
      • 棧滿狀態

        st.top = MAXSIZE - 1;			//MAXSIZE是設置的棧內最大存儲元素個數
        
      • 進棧操作

        st.Data[++st.top] = dat;		//由於st.top初值爲-1,這裏需要先進行加1
        
      • 出棧操作

        dat = st.Data[st.top--];		//對應於進棧操作,這裏st.top先取值再減1
        
  2. 隊列

    • 與棧一樣,隊列的順序存儲指的是利用一組地址連續的存儲單元存放隊列中的元素,並設置兩個指針分別指示隊頭元素和隊尾元素的存儲位置的變量,分別稱爲隊頭指針front和隊尾指針rear。

    • 元素進隊的時候,rear指針向後移動;元素出隊的時候,front指針向後移動,這樣到最後,就會出現假溢出。因此就產生了循環隊列 。

    • 循環隊列

      • 把數組弄成一個環,讓front,rear指針沿着環走,這樣就不永遠不會出現兩指針到數組的盡頭不會往下走的情況了

      • 循環隊列(qu)的4個要素

        • 隊空狀態

          qu.rear = qu.front;					//隊首等於隊尾
          
        • 隊滿狀態

          (qu.rear+1) % MAXSIZE == qu.front; 	//隊尾元素加1,取餘最大元素個數若等於隊頭,則滿 
          
        • 進隊操作

          qu.rear = (qu.rear+1) % MAXSIZE;	//先將隊尾下標向後移動一個位置
          qu.Data[qu.rear] = dat;				//進隊
          
        • 出隊操作

          qu.front = (qu.front+1) % MAXSIZE;	//先將隊頭的下標向後移動一個位置
          dat = qu.Data[qu.front];			//出隊
          
(三)棧和隊列的鏈式存儲結構
  1. 棧的鏈式存儲結構

    • 棧的鏈式存儲結構稱爲鏈棧

    • 棧只能在棧頂進行插入和刪除,所以棧頂指針是必須的

    • 鏈棧(lst)的4個要素:兩個狀態,兩個操作

      • 棧空狀態

        lst->next == NULL;					//下個位置無結點
        
      • 棧滿狀態:一般內存足夠大,不存在棧滿狀態,

      • 進棧操作(指針p所指進棧結點)

        p->next = lst->next;				//先將棧頂指針指向的結點賦值給p結點,使在其後
        lst->next = p;						//再將p結點的地址賦給棧頂結點,使p爲棧頂指針所指
        
      • 出棧操作(p所指出棧結點,x指結點內的數據信息)

        p = lst->next;						//將要出棧的結點賦值給p
        x = p->data;						//獲取結點中的數據
        lst->next = p->next;				//將棧頂指針向後指
        
  2. 隊列的鏈式存儲結構

    • 隊列的鏈式存儲結構稱爲鏈隊列

    • 鏈隊(lqu)的4個要素:

      • 隊空狀態:

        lqu->front == NULL || lqu->rear == NULL	//剛開始,兩者都爲空
        
      • 隊滿狀態:一般內存足夠大,不存在棧滿狀態,

      • 進隊操作(指針p爲進隊結點)

        lqu->rear->next = p;					//先將p結點加到隊尾指向的結點的後面 
        lqu->rear = p;							//再將p結點所在地址賦值給隊尾結點
        
      • 出隊操作(p爲出隊結點)

        p = lqu.front;							//先將要出隊的元素地址賦值給p
        x = p.data;								//取出p結點的數據
        lqu.front = p.next;						//再將p結點後的結點的地址賦值給隊頭元素
        free(p);								//釋放內存
        
    • 隊頭指針指向鏈隊列的頭結點,隊尾指針指向終端節點。

(四)棧和隊列的應用
    • 四則運算表達式求值
    • 括號的匹配
  1. 隊列
    • 隊列在計算機系統的應用
(五)特殊矩陣的壓縮存儲
  1. 壓縮存儲
    • 指多個值相同的元素只分配一個存儲空間,隊零元素不分配存儲空間。其目的爲了節省空間
  2. 特殊矩陣
    • 具有許多相同矩陣元素或零元素,並且這些相同元素或零元素的分佈有一定規律。常見的特殊矩陣包括:對稱矩陣,三角矩陣,對角矩陣。

    • 對稱矩陣
      在這裏插入圖片描述

      • 一個n階方陣A[n] [n]中的元素滿足A[i] [j] == A[j] [i],則稱其爲n階對稱矩陣。
      • 對稱矩陣中的元素關於主對角線對稱,因此存儲的時候只存儲矩陣中上三角或者下三角矩陣,使得對稱元素共享一個存儲空間。
      • 將這些元素按照下標,依次存儲到數組中,那麼數組下標與此矩陣的行列號有什麼規律呢?下面以i表示矩陣的行號,j表示矩陣的列號,k表示數組的下標,且都以下三角存儲爲例:
        當矩陣的第一個元素以a[0] [0] 開始時,公式如下

      k=(1+i)i2+j                       (i>=j) k = \frac{(1+i)i}{2} + j \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i>=j)

      k=(1+j)j2+i                       (i<j) k = \frac{(1+j)j}{2} + i \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i<j)

        當矩陣的第一個元素以a[1] [1] 開始時,公式如下

      k=i(i1)2+j1                       (i>=j) k = \frac{i(i-1)}{2} + j - 1 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i>=j)

      k=j(j1)2+i1                       (i<j) k = \frac{j(j-1)}{2} + i - 1 \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (i<j)

    • 上三角矩陣/下三角矩陣

      • 上三角矩陣:矩陣下三角部分(不包括對角線)元素全部爲C,C可以是0.
        - [外鏈圖片轉存中...(img-mo6fRCKu-1565011737441)]
      • 下三角矩陣:矩陣上三角部分(不包括對角線)元素全部爲C,C可以是0。
        - [外鏈圖片轉存中...(img-VojbI9ik-1565011737443)]
      • 其存儲方式和對稱矩陣的存儲方式一樣,只需存儲對角線及對角線一側元素和對角線另一側的元素C即可。
    • 對角矩陣

      • 除主對角線以及其上下兩條帶狀取餘內的元素外,其餘元素皆爲C,C可以爲0.- [外鏈圖片轉存中...(img-NnNNaotx-1565011737449)]
      • 上圖中的b爲矩陣的半帶寬,(2b+1)爲矩陣的帶寬。
      • 同理,將此對角矩陣存入到數組中,有什麼規律呢?下面以i表示矩陣的行號,j表示矩陣的列號,k表示數組的下標,以三對角矩陣爲例
        則當矩陣的第一個元素以a[0] [0] 開始時,公式如下

      k=2i+j                       (ij<=1) k = 2i + j \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (| i-j |<= 1)

        則當矩陣的第一個元素以a[0] [0] 開始時,公式如下
k=2(i1)+j1                  ((ij<=1) k = 2(i-1) + j - 1\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ ( (| i-j |<= 1)

(六)算法實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章