數據結構與算法——線性表

1.概念

線性表能夠看作一種抽象的概念,也能夠做爲一種抽象數據類型,一個線性表是某類元素的集合,還記錄着元素之間的一種順序關係。至關於一個抽象類,只作定義。python

 

2.具體實現

1.順序表

順序表的基本實現方式很是簡單:表中元素順序存放在一片足夠大的連續儲存區間裏,首元素存入儲存區的開始位置,其他元素依次順序存放,元素之間的邏輯關係經過元素在儲存區裏的物理位置表示(隱式表示元素之間的關係)佈局

順序表在內存中的佈局方式:spa

1.順序表基本操做的實現

 

 

  1. 建立和訪問操做

建立空表時,須要分配一塊元素儲存,記錄表的容量,並將元素計數設置爲0,複雜度爲O(1)3d

  1. 簡單判斷操做

 

 

判斷表空或表滿的操做很容易實現,複雜度都爲O(1)指針

  1. 訪問給定下標i的元素

不依賴表中元素個數,所以也是O(1)操做對象

  1. 遍歷操做

要順序訪問表中元素,在遍歷過程當中記錄遍歷到達位置,再算出元素位置,便可獲取到元素。獲取每個元素的複雜度爲O(1),因此遍歷整個表的複雜度爲O(n)。blog

  1. 查找給定元素d的位置

這種操做稱爲檢索或查找,採用遍歷的操做,順序比較,時間複雜度O(n)。內存

  1. 查找給定元素d在位置k以後第一次出現的位置

同5相同,只不過從位置k之後遍歷。class

  1. 加入元素

在表的尾端加入和刪除都很簡單,時間複雜度爲O(1)。在其餘位置添加和刪除就要麻煩些,須要移動操做位置後面的數據,向前移動或向後移動,時間複雜度爲O(len-i),i爲操做位置。效率

  1. 刪除元素

尾端刪除元素操做簡單,時間複雜度爲O(1),通常位置刪除O(n),基於條件的刪除O(n)。

總結:

優勢:O(1)時間的按位置訪問,元素在表裏儲存緊湊,除表元素外,只須要O(1)空間存放少許的輔助信息。

缺點:須要連續的儲存區存放表中元素,若是表很大,就須要大片的連續內存空間,一旦肯定了儲存塊的大小,不會隨着數據的插入和刪除操做進行變更,會有大量空閒單元存在,形成浪費。

 

2.順序表的結構

兩種基本實現方式

    1. 一體式結構
    2. 分離式結構

 

  1. 一體式分析

實現比較緊湊,有關信息集中在一塊兒,總體性強,易於管理。

建立後儲存區大小固定

  1. 分離式分析

表中只保存於整個表有關的信息,實際元素放在另外一個獨立的元素儲存區對象裏,經過連接於基本表對相關連,這樣的表對象大小統一,但一個表須要兩個獨立的對象實現,建立和管理工做複雜。分離式實現的最大優勢是帶來了一種新的可能,能夠在標識不變的狀況下,爲其對象換一塊元素儲存區,也就是說能夠改變表的容量。

      • 另外申請一塊更大的存儲區
      • 把表中已有元素複製到新存儲區
      • 用新的元素存儲區替換原來的元素存儲區
      • 實際加入新元素

在擴容的時候若是每次只擴大10個元素儲存位置,那麼在大量數據插入的時候,須要不停的更換存儲位置,元素頻繁複制遷移。若是每次擴大當前儲存量的一倍,當數據較大的時候,會形成大量的存儲空間浪費。因此擴容的時候採用的策略也須要權衡利弊。

 

3.python的list

基本實現

    1. 基於下標高效訪問和更新
    2. 容許任意加入元素,並且在加入過程當中表的id不變

解決方案

    1. 因爲須要O(1)時間的元素訪問,並能維持元素的順序,這種表只能採用連續表技術
    2. 要求容納任意多的元素,就必須能更換元素存儲區,因此只能採用分離式技術實現。

實際策略

    1. 在創建空表或很小的表時,系統分配一塊能容納8個元素的存儲區,若是滿了就換一塊4倍大的存儲區
    2. 若是表的容量達到50000時,換儲存區時容量加倍

 

4.順序表的簡單總結

  1. 最重要的特色是O(1)時間的定位元素訪問,更新。不少簡單操做的效率也比較高。
  2. 最麻煩的是加入,刪除等操做的效率問題
  3. 須要連續的存儲空間
  4. 結構不夠靈活

 

2.連接表

    1. 單鏈表

在這樣的結構中,爲了掌握一個表,只須要用一個變量保存着這個表的首節點的引用

    • 一個單鏈表由一些具體的表節點構成
    • 每一個節點是一個對象,有本身的標識,也稱爲該節點的連接
    • 節點之間經過連接創建起單向的順序聯繫
    • 鏈表的結束只需在最後的節點的連接域設置一個None。
2.1.1. 基本操做
    • 建立空鏈表:只須要把相應的表頭變量設置爲空連接。
    • 刪除鏈表:丟棄這個鏈表裏的全部節點,python裏只須要將表指正賦值爲None,python解釋器會自動回收不用的存儲。
    • 判斷是否爲空:將表頭變量的值與空連接值比較
    • 判斷是否滿:通常而言鏈表不會滿,除非程序用完了全部的存儲空間
    • 首端插入:
      • 建立一個新節點並存入數據
      • 把原鏈表首節點的連接存入新節點的連接域next
      • 修改表頭變量,使之指向新節點
    • 通常狀況下的插入
      • 找到插入位置
      • 執行首端操做的三步
    • 刪除表首元素:只需修改表頭指針,令其指向第二個節點
    • 通常狀況下的刪除:找到元素前一節點所在位置,next域改成元素後一節點的連接
    • 掃描、定位和遍歷:因爲單鏈表只有一個方向的連接,開始時只有表頭的連接在掌握中,因此對錶內內容的一切檢查都只能從表頭開始,沿表中連接逐步進行,過程稱爲掃描。
      • 按下標定位
      • 按元素定位

 

    • 操做複雜度
      • 建立空表:O(1)
      • 刪除表:在python裏是O(1)
      • 判斷空:O(1)
      • 加入元素或刪除:
      • 首端加入:O(1)
      • 尾端加入:O(n)
      • 隨意加入:O(n),平均和最壞狀況都是
      • 求表的長度:須要掃描整個,得出長度,也能夠把長度記錄爲表的數據成分,O(1)
相關文章
相關標籤/搜索