20172313 2018-2019-1 《程序設計與數據結構》課堂測試修改報告

20172313 2018-2019-1 《程序設計與數據結構》課堂測試修改報告

課程:《程序設計與數據結構》
班級: 1723
姓名: 餘坤澎
學號:20172313
實驗教師:王志強
實驗日期:2018年10月19日
必修/選修: 必修數組

題目內容

測試原理

  • 順序查找:原理較爲簡單,經過遍歷列表逐個比較進行查找。
  • 折半查找:首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查找關鍵字比較,若是二者相等,則查找成功;不然利用中間位置記錄將表分紅前、後兩個子表,若是中間位置記錄的關鍵字大於查找關鍵字,則進一步查找前一子表,不然進一步查找後一子表。重複以上過程,直到找到知足條件的記錄,使查找成功,或直到子表不存在爲止,此時查找不成功。
  • 哈希查找(散列查找):
    • 概念理解:什麼是哈希查找呢?在弄清楚什麼是哈希查找以前,咱們要弄清楚哈希技術,哈希技術是在記錄的存儲位置和記錄的關鍵字之間創建一個肯定的對應關係f,使得每一個關鍵字key對應一個存儲位置f(key)。查找時,根據這個肯定的對應關係找到給定值的映射f(key),若查找集合中存在這個記錄,則一定在f(key)的位置上。哈希技術既是一種存儲方法,也是一種查找方法。
    • 哈希函數大致有六種構造方法:數據結構

      1,直接定址法:
      函數公式:f(key)=a*key+b (a,b爲常數)
      這種方法的優勢是:簡單,均勻,不會產生衝突。可是須要事先知道關鍵字的分佈狀況,適合查找表較小而且連續的狀況。
      2,數字分析法:
      好比咱們的11位手機號碼「136XXXX7887」,其中前三位是接入號,通常對應不一樣運營公司的子品牌,如130是聯通如意通,136是移動神州行,153是電信等。中間四們是HLR識別號,表示用戶歸屬地。最後四們纔是真正的用戶號。
      若咱們如今要存儲某家公司員工登記表,若是用手機號碼做爲關鍵字,那麼極有可能前7位都是相同的,因此咱們選擇後面的四們做爲哈希地址就是不錯的選擇。
      3,平方取中法:
      故名思義,好比關鍵字是1234,那麼它的平方就是1522756,再抽取中間的3位就是227做爲哈希地址。
      4,摺疊法:
      摺疊法是將關鍵字從左到右分割成位數相等的幾個部分(最後一部分位數不夠能夠短些),而後將這幾部分疊加求和,並按哈希表表長,取後幾位做爲哈希地址。
      好比咱們的關鍵字是9876543210,哈希表表長三位,咱們將它分爲四組,987|654|321|0 ,而後將它們疊加求和987+654+321+0=1962,再求後3位即獲得哈希地址爲962,哈哈,是否是頗有意思。
      5,除留餘數法:
      函數公式:f(key)=key mod p (p<=m)m爲哈希表表長。
      這種方法是最經常使用的哈希函數構造方法。
      6,隨機數法:
      函數公式:f(key)= random(key)。
      這裏random是隨機函數,當關鍵字的長度不等是,採用這種方法比較合適。dom

    • 衝突的產生:兩個不一樣的的關鍵字可能對應同一個內存地址。 這樣,將致使後方的關鍵字沒法儲存。
    • 衝突的解決:
      • 開放定值法:這種方法也稱再散列法,其基本思想是:當關鍵字key的哈希地址p=H(key)出現衝突時,以p爲基礎,產生另外一個哈希地址p1,若是p1仍然衝突,再以p爲基礎,產生另外一個哈希地址p2,…,直到找出一個不衝突的哈希地址pi ,將相應元素存入其中。這種方法有一個通用的再散列函數形式:
        Hi=(H(key)+di)% m i=1,2,…,n
        其中H(key)爲哈希函數,m 爲表長,di稱爲增量序列。增量序列的取值方式不一樣,相應的再散列方式也不一樣。主要有如下三種:函數

        線性探測再散列
        dii=1,2,3,…,m-1
        這種方法的特色是:衝突發生時,順序查看錶中下一單元,直到找出一個空單元或查遍全表。
        二次探測再散列
        di=12,-12,22,-22,…,k2,-k2 ( k<=m/2 )
        這種方法的特色是:衝突發生時,在表的左右進行跳躍式探測,比較靈活。
        僞隨機探測再散列
        di=僞隨機數序列。
        具體實現時,應創建一個僞隨機數發生器,(如i=(i+p) % m),並給定一個隨機數作起點。
        例如,已知哈希表長度m=11,哈希函數爲:H(key)= key % 11,則H(47)=3,H(26)=4,H(60)=5,假設下一個關鍵字爲69,則H(69)=3,與47衝突。
        若是用線性探測再散列處理衝突,下一個哈希地址爲H1=(3 + 1)% 11 = 4,仍然衝突,再找下一個哈希地址爲H2=(3 + 2)% 11 = 5,仍是衝突,繼續找下一個哈希地址爲H3=(3 + 3)% 11 = 6,此時再也不衝突,將69填入5號單元。
        若是用二次探測再散列處理衝突,下一個哈希地址爲H1=(3 + 12)% 11 = 4,仍然衝突,再找下一個哈希地址爲H2=(3 - 12)% 11 = 2,此時再也不衝突,將69填入2號單元。
        若是用僞隨機探測再散列處理衝突,且僞隨機數序列爲:2,5,9,……..,則下一個哈希地址爲H1=(3 + 2)% 11 = 5,仍然衝突,再找下一個哈希地址爲H2=(3 + 5)% 11 = 8,此時再也不衝突,將69填入8號單元。性能

      • 再哈希法:這種方法是同時構造多個不一樣的哈希函數:Hi=RH1(key) i=1,2,…,k
        當哈希地址Hi=RH1(key)發生衝突時,再計算Hi=RH2(key)……,直到衝突再也不產生。這種方法不易產生彙集,但增長了計算時間。
      • 鏈地址法:這種方法的基本思想是將全部哈希地址爲i的元素構成一個稱爲同義詞鏈的單鏈表,並將單鏈表的頭指針存在哈希表的第i個單元中,於是查找、插入和刪除主要在同義詞鏈中進行。鏈地址法適用於常常進行插入和刪除的狀況。
    • 方法優勢
      • 開放定值法:1.記錄更容易進行序列化(serialize)操做。 2.若是記錄總數能夠預知,能夠建立完美哈希函數,此時處理數據的效率是很是高的。
      • 鏈地址法: ①對於記錄總數頻繁可變的狀況,處理的比較好(也就是避免了動態調整的開銷)。 ②因爲記錄存儲在結點中,而結點是動態分配,不會形成內存的浪費,因此尤爲適合那種記錄自己尺寸(size)很大的狀況,由於此時指針的開銷能夠忽略不計了。 ③刪除記錄時,比較方便,直接經過指針操做便可 。
    • 方法缺點:
      • 開放定值法:1.存儲記錄的數目不能超過桶數組的長度,若是超過就須要擴容,而擴容會致使某次操做的時間成本飆升,這在實時或者交互式應用中可能會是一個嚴重的缺陷 2.使用探測序列,有可能其計算的時間成本太高,致使哈希表的處理性能下降 3.因爲記錄是存放在桶數組中的,而桶數組必然存在空槽,因此當記錄自己尺寸(size)很大而且記錄總數規模很大時,空槽佔用的空間會致使明顯的內存浪費 4.刪除記錄時,比較麻煩。好比須要刪除記錄a,記錄b是在a以後插入桶數組的,可是和記錄a有衝突,是經過探測序列再次跳轉找到的地址,因此若是直接刪除a,a的位置變爲空槽,而空槽是查詢記錄失敗的終止條件,這樣會致使記錄b在a的位置從新插入數據前不可見,因此不能直接刪除a,而是設置刪除標記。這就須要額外的空間和操做。
      • 鏈地址法: 1.存儲的記錄是隨機分佈在內存中的,這樣在查詢記錄時,相比結構緊湊的數據類型(好比數組),哈希表的跳轉訪問會帶來額外的時間開銷 2.若是全部的 key-value 對是能夠提早預知,並以後不會發生變化時(即不容許插入和刪除),能夠人爲建立一個不會產生衝突的完美哈希函數(perfect hash function),此時封閉散列的性能將遠高於開放散列 ③因爲使用指針,記錄不容易進行序列化(serialize)操做

測試結果

  • 畫出順序查找的順序表和成功平均查找長度。
    學習

  • 畫出折半查找的順序表和成功平均查找長度。
    測試

  • 用線性探查法實現散列查找。
    設計

  • 用鏈地址法實現散列查找。
    3d

其餘

  前幾周的內容相對來講比較簡單,因此學習的時候有些放鬆,此次測試也讓我明白本身不會的東西還有不少,因此不能懈怠,還要繼續努力纔是,但願本身能在之後的學習生活中能繼續進步!指針

相關文章
相關標籤/搜索