順序表的實現 ------ Python數據結構與算法第3章

1. 順序表的形式

       在程序中,經常需要將一組(通常是同爲某個類型的)數據元素作爲整體管理和使用,需要創建這種元素組,用變量記錄它們,傳進傳出函數等。一組數據中包含的元素個數可能發生變化(可以增加或刪除元素)。

       對於這種需求,最簡單的解決方案便是將這樣一組元素看成一個序列,用元素在序列裏的位置和順序,表示實際應用中的某種有意義的信息,或者表示數據之間的某種關係。

       這樣的一組序列元素的組織形式,我們可以將其抽象爲 線性表。一個線性表是某類元素的一個集合,還記錄着元素之間的一種順序關係。線性表是最基本的數據結構之一,在實際程序中應用非常廣泛,它還經常被用作更復雜的數據結構的實現基礎。根據線性表的實際存儲方式,分爲兩種實現模型:

① 順序表:將元素順序地存放在一塊連續的存儲區裏,元素間的順序關係由它們的存儲順序自然表示。
② 鏈表:將元素存放在通過鏈接構造起來的一系列存儲塊中。

2. 順序表的結構與實現
2.1 順序表的結構

在這裏插入圖片描述
       一個順序表的完整信息包括兩部分,一部分是表中的元素集合,另一部分是爲實現正確操作而需記錄的信息,即有關表的整體情況的信息,這部分信息主要包括 元素存儲區的容量當前表中已有的元素個數 兩項。

2.2 順序表的兩種基本實現方式

在這裏插入圖片描述在這裏插入圖片描述
       圖a爲一體式結構,存儲表信息的單元與元素存儲區以連續的方式安排在一塊存儲區裏,兩部分數據的整體形成一個完整的順序表對象。一體式結構整體性強,易於管理。但是 由於數據元素存儲區域是表對象的一部分,順序表創建後,元素存儲區就固定了。

       圖b爲分離式結構,表對象裏只保存與整個表有關的信息(即容量和元素個數),實際數據元素存放在另一個獨立的元素存儲區裏,通過鏈接與基本表對象關聯。

2.3 元素存儲區替換

       一體式結構由於順序表信息區與數據區連續存儲在一起,所以若想更換數據區,則只能整體搬遷,即整個順序表對象(指存儲順序表的結構信息的區域)改變了。分離式結構若想更換數據區,只需將表信息區中的數據區鏈接地址更新即可,而該順序表對象不變。

2.4 元素存儲區擴充

       採用 分離式結構的順序表,若將數據區更換爲存儲空間更大的區域,則可以在不改變表對象的前提下對其數據存儲區進行了擴充,所有使用這個表的地方都不必修改。只要程序的運行環境(計算機系統)還有空閒存儲,這種表結構就不會因爲滿了而導致操作無法進行。人們把採用這種技術實現的順序表稱爲 動態順序表,因爲其容量可以在使用中動態變化。

擴充的兩種策略:

① 每次擴充增加固定數目的存儲位置,如 每次擴充增加10個元素位置,這種策略可稱爲線性增長。特點:節省空間,但是擴充操作頻繁,操作次數多。

② 每次擴充 容量加倍,如每次擴充增加一倍存儲空間。特點:減少了擴充操作的執行次數,但可能會浪費空間資源。以空間換時間,推薦的方式

3. 順序表的操作

增加元素:
在這裏插入圖片描述
a. 尾端加入元素,時間複雜度爲O(1)
b. 非保序的加入元素(不常見),時間複雜度爲O(1)
c. 保序的元素加入,時間複雜度爲O(n)

刪除元素:
在這裏插入圖片描述
a. 刪除表尾元素,時間複雜度爲O(1)
b. 非保序的元素刪除(不常見),時間複雜度爲O(1)
c. 保序的元素刪除,時間複雜度爲O(n)

4. Python中的順序表

       Python中的list和tuple兩種類型採用了順序表的實現技術,具有前面討論的順序表的所有性質。tuple是不可變類型,即不變的順序表,因此不支持改變其內部狀態的任何操作,而其他方面,則與list的性質類似。list的基本實現技術:

       Python標準類型list就是一種元素個數可變的線性表,可以加入和刪除元素,並在各種操作中維持已有元素的順序(即保序),而且還具有以下行爲特徵:

① 基於下標(位置)的高效元素訪問和更新,時間複雜度應該是O(1);爲滿足該特徵,應該採用順序表技術,表中元素保存在一塊連續的存儲區中。

② 允許任意加入元素,而且在不斷加入元素的過程中,表對象的標識(函數id得到的值)不變。爲滿足該特徵,就必須能更換元素存儲區,並且爲保證更換存儲區時list對象的標識id不變,只能 採用分離式實現技術。

       在Python的官方實現中,list就是一種採用分離式技術實現的動態順序表。這就是爲什麼用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。在Python的官方實現中,list實現採用瞭如下的策略:在建立空表(或者很小的表)時,系統分配一塊能容納8個元素的存儲區;在執行插入操作(insert或append)時,如果元素存儲區滿就換一塊4倍大的存儲區。但如果此時的表已經很大(目前的閥值爲50000),則改變策略,採用加一倍的方法。引入這種改變策略的方式,是爲了避免出現過多空閒的存儲位置。

Github:https://github.com/ThanlonSmith/Data-Structure-Python3

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