黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表

系統(tǒng) 2074 0

文章目錄

    • 內(nèi)存
    • 1. 順序表的形式(元素內(nèi)置vs外置)
      • 元素內(nèi)置
      • 元素外置
    • 2. 順序表結(jié)構(gòu)(一體式vs分離式)
      • 一體式存儲
        • 更換數(shù)據(jù)
      • 分離式存儲
        • 更換數(shù)據(jù)
        • 數(shù)據(jù)區(qū)擴(kuò)充
    • 3. 順序表的操作
      • 增加元素
      • 刪除元素
    • 4. python中的順序表
      • List的基本實(shí)現(xiàn)技術(shù)

內(nèi)存

內(nèi)存以1Byte=8bits來作為存儲單位。操作系統(tǒng)尋址最小單位為字節(jié),一個字節(jié)為8bit。
一個整形int占4Byte.在計算機(jī)中占用內(nèi)存如下:

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第1張圖片

0x01-0x04對應(yīng)的內(nèi)存存儲的就是整體int a,所以我們可以看到這時把它當(dāng)作一個整體來對待。
如果是char類型則把2個byte來當(dāng)作一個整體來對待,因?yàn)閏har占用2個byte
所以基本數(shù)據(jù)類型就是告訴內(nèi)存應(yīng)該如何存儲數(shù)據(jù)。

如果該數(shù)據(jù)結(jié)構(gòu)是在內(nèi)存中是連續(xù)存放的。則有如下結(jié)構(gòu)

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第2張圖片

1. 順序表的形式(元素內(nèi)置vs外置)

元素內(nèi)置與外置主要區(qū)分的是是否存在與同一塊連續(xù)內(nèi)存區(qū)而決定的 存儲元素類型是否相同

元素內(nèi)置

將元素順序地存放在一塊連續(xù)的存儲區(qū)里,元素間的順序關(guān)系由它們的存儲順序自然表示。
下圖表示的是順序表的基本形式,數(shù)據(jù)元素本身連續(xù)存儲,每個元素所占的存儲單元大小固定相同。 例如java中的array元素類型要相同

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第3張圖片

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第4張圖片

依次把這組數(shù)據(jù)存入內(nèi)存,這組數(shù)據(jù)變量名為Li,Li其實(shí)代表的就是起始地址0x23;地址占用內(nèi)存統(tǒng)一的為4Byte。
這時我想去讀Li第0個元素為Li[0]。
而當(dāng)我們要讀Li[3],開始我們需要從頭開始找0x23往后走3步也就是走到 0x23+3*4Byte=0x35 ,到這個地址的時候就可以返回該地址存儲的值了。
這時我們就知道為何數(shù)組存儲要從Li[0]開始,這里的角標(biāo)起始代表的就是偏移量,計算機(jī)通過偏移量來得到目標(biāo)地址,如Li[3]就計算偏移量為3的地址。
故,訪問指定元素時無需從頭遍歷,通過計算便可獲得對應(yīng)地址,其時間復(fù)雜度為O(1)。

元素外置

如果元素的大小不統(tǒng)一 如python中的list存儲元素類型可以不同。則須采用圖b的元素外置的形式,將實(shí)際數(shù)據(jù)元素另行存儲,而順序表中各單元位置保存對應(yīng)元素的地址信息(即鏈接)。注意,圖b中的c不再是數(shù)據(jù)元素的大小,而是存儲一個鏈接地址所需的存儲量,這個量通常很小與int型一樣為4Byte。

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第5張圖片

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第6張圖片

找一個位置把每個數(shù)據(jù)存起來,但是每個數(shù)據(jù)的地址可以不連續(xù)。
這時每個地址指向?qū)?yīng)數(shù)據(jù),而這時我們找一塊連續(xù)的內(nèi)存把每個數(shù)據(jù)的地址存儲起來。
這塊連續(xù)空間存儲全部都是地址,每個地址指向一個數(shù)據(jù)內(nèi)存。
這時Li[0]為0x324地址,然后找到該地址中的數(shù)據(jù)0x100然后找到0x100指向的內(nèi)存空間為數(shù)據(jù)12。
也就是把數(shù)據(jù)存儲到順序表之外,元素外置,可以存儲不同的數(shù)據(jù)類型。

圖b這樣的順序表也被稱為對實(shí)際數(shù)據(jù)的索引,這是最簡單的索引結(jié)構(gòu)。

2. 順序表結(jié)構(gòu)(一體式vs分離式)

一個順序表的完整信息包括兩部分,一部分是表中的 元素存儲區(qū) ,另一部分為 表頭信息 :主要包括元素存儲區(qū)的 容量 和當(dāng)前表中 已存的元素個數(shù)
一體式和分離式主要決定的是 存儲區(qū)大小是否為固定的

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第7張圖片

一體式存儲

表頭信息和數(shù)據(jù)區(qū)一起存儲
數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第8張圖片
存儲表信息的單元與元素存儲區(qū)以連續(xù)的方式安排在一塊存儲區(qū)里,兩部分?jǐn)?shù)據(jù)的整體形成一個完整的順序表對象。
一體式結(jié)構(gòu)整體性強(qiáng),易于管理。但是由于數(shù)據(jù)元素存儲區(qū)域是表對象的一部分,順序表創(chuàng)建后,元素存儲區(qū)就固定了。 比如java中的數(shù)組。大小是固定的

更換數(shù)據(jù)

所以若想更換數(shù)據(jù)區(qū),則只能整體搬遷,即整個順序表對象(指存儲順序表的結(jié)構(gòu)信息的區(qū)域)改變了。

分離式存儲

表頭信息和存儲區(qū)分開存儲
數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第9張圖片
采用分離式間接訪問,多了一次計算。
表對象里只保存與整個表有關(guān)的信息(即容量和元素個數(shù)),實(shí)際數(shù)據(jù)元素存放在另一個獨(dú)立的元素存儲區(qū)里,通過鏈接與基本表對象關(guān)聯(lián)。 類似于java的List
為了考慮數(shù)據(jù)動態(tài)變化,盡量使用分離式。

更換數(shù)據(jù)

若想更換數(shù)據(jù)區(qū),只需將表信息區(qū)中的數(shù)據(jù)區(qū)鏈接地址更新即可,而該順序表對象不變。
人們把采用這種技術(shù)實(shí)現(xiàn)的順序表稱為動態(tài)順序表,因?yàn)槠淙萘靠梢栽谑褂弥袆討B(tài)變化。

數(shù)據(jù)區(qū)擴(kuò)充

當(dāng)進(jìn)行存儲區(qū)擴(kuò)充時,相當(dāng)于新建一個存儲區(qū),但是新建這個存儲區(qū)究竟要多大。
擴(kuò)充的兩種策略:

  1. 每次擴(kuò)充 增加固定數(shù)目 的存儲位置,如每次擴(kuò)充增加10個元素位置,這種策略可稱為線性增長。特點(diǎn):節(jié)省空間,但是擴(kuò)充操作頻繁,操作次數(shù)多。
  2. 每次 擴(kuò)充容量加倍 ,如每次擴(kuò)充增加一倍存儲空間。特點(diǎn):減少了擴(kuò)充操作的執(zhí)行次數(shù),但可能會浪費(fèi)空間資源。以空間換時間, 推薦的方式

3. 順序表的操作

增加元素

當(dāng)我們?nèi)萘繛?,現(xiàn)在數(shù)字為4,我們想添加一個元素111時:
數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第10張圖片

  1. 尾端加入元素,直接加,時間復(fù)雜度為O(1)
  2. 非保序的加入元素(不常見),時間復(fù)雜度為O(1)
  3. 保序的元素插入,插入到[1]到位置,我們需要把111放到位置[1],后面的元素都需要向后移一位。
    比如我們要插入隊(duì)頭,那么后面元素都向后移一位,也就是操作n次,那么時間復(fù)雜度為O(n)。、

刪除元素

數(shù)據(jù)結(jié)構(gòu)與算法(python描述)(四)—— 順序表_第11張圖片

  1. 刪除表尾元素,時間復(fù)雜度為O(1)
  2. 非保序的元素刪除(不常見),時間復(fù)雜度為O(1)
  3. 保序的元素刪除,表頭刪除之后,其他元素都向前提一位,時間復(fù)雜度為O(n)

4. python中的順序表

Python中的list和tuple兩種類型采用了順序表的實(shí)現(xiàn)技術(shù),tuple是不可變類型,即不變的順序表,因此不支持改變其內(nèi)部狀態(tài)的任何操作,而其他方面,則與list的性質(zhì)類似。

List的基本實(shí)現(xiàn)技術(shù)

Python標(biāo)準(zhǔn)類型list就是一種元素個數(shù)可變的線性表,可以加入和刪除元素,并在各種操作中維持已有元素的順序(即保序),而且還具有以下行為特征:

  • 基于下標(biāo)(位置)的高效元素訪問和更新,時間復(fù)雜度應(yīng)該是O(1);
    為滿足該特征,應(yīng)該采用順序表技術(shù),表中元素保存在一塊連續(xù)的存儲區(qū)中,采用元素外置。
  • 允許任意加入元素,而且在不斷加入元素的過程中,表對象的標(biāo)識(函數(shù)id得到的值)不變。
    為滿足該特征,就必須能更換元素存儲區(qū),并且為保證更換存儲區(qū)時list對象的標(biāo)識id不變,只能采用分離式實(shí)現(xiàn)技術(shù)。

在Python的官方實(shí)現(xiàn)中,list就是一種采用 分離式技術(shù)實(shí)現(xiàn)的動態(tài)順序表 。這就是為什么用list.append(x) (或 list.insert(len(list), x),即尾部插入)比在指定位置插入元素效率高的原因。

在Python的官方實(shí)現(xiàn)中,list實(shí)現(xiàn)采用了如下的策略:在建立空表(或者很小的表)時,系統(tǒng)分配一塊能容納8個元素的存儲區(qū);在執(zhí)行插入操作(insert或append)時,如果元素存儲區(qū)滿就換一塊4倍大的存儲區(qū)。但如果此時的表已經(jīng)很大(目前的閥值為50000),則改變策略,采用加一倍的方法。引入這種改變策略的方式,是為了避免出現(xiàn)過多空閑的存儲位置。


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論