數據結構與算法(C++)學習筆記:查找(持續更新中)

基本概念

  • 生活中處處有查找,例如:搜索引擎、大數據問題等等。
  • 我們學習查找想要解決的問題:對於超大數據量,如何提高查找的效率?
  • 基本概念:
  1. 關鍵碼:用以標識一個記錄的某個數據項。如果該關鍵碼可以唯一的標識一條記錄,則稱爲主關鍵碼,反之爲次關鍵碼。
  2. 查找:在具有相同類型的記錄集中找出滿足給定條件的記錄。
  3. 查找結果:在查找集中找到匹配的記錄,稱爲查找成功;否則查找失敗。一般情況下,查找需要返回記錄的位置。
    基本概念

P.S.

  • 散列技術其實有很多,例如HASH哈希(題外話:在python中,字典就是一種哈希映射~欲知詳情,請查看我的另一篇筆記
    ),散列查找的效率是相當高的,在最近十幾年才崛起。
  • 二叉排序樹與平衡二叉樹的區別?
    因爲對於一組無序數據,通過二叉排序樹排序以後得到的樹有很大可能是不平衡的(左右子樹大小相差太多),而平衡二叉樹稱得上是二叉排序樹的升級版,可以解決左右子樹不平衡的問題。
    **思考:**查找結構與存儲結構有什麼區別?

線性表查找

順序查找

問題: 對於亂序數據,如何快速查找出關鍵字Key是否在亂序中?若是,如何返回位置?

方法一:簡單粗暴的直接查找

int search(int a[],int n,int key)
{
    for(int i=0;i<n;i++)//①
        if(a[i] == key)//②
            return i+1;//找到key,返回位置
    return 0;//沒有找到,返回0
}

反思: 上述代碼的時間複雜度?是O(n^2),因爲有二次比較。
思考: 如何進一步提高效率?

方法二:哨兵法–用空間換時間

思想: 對於長度爲n的亂序表,另建一個長度爲n+1的表,其中a[0]做哨兵,其值賦爲key。哨兵的意義–使函數無論如何都會返回一個值,而且只需要比較一次。

int search(int a[],int n,int key)
{
    a[0] = key;  //哨兵
    for(int i=n;a[i]!=key;i--);  //從後向前查找
    return i; //如果找到key,就返回位置i,沒有找到,就返回0
}

哨兵法順序表查找

計算ASL:

  1. 查找不成功 ASL = n+1
  2. 查找成功
    哨兵法ASL

折半查找(敲黑板:必考題)

思考: 折半法的前提是什麼?待查找序列爲有序表。
基本思想: 先確定待查記錄所在的範圍,再用二分法逐步縮小範圍直到找到或找不到且查完整個表。
再思考: 對存放在數組中的有序表,如何快速找到Key?
折半
折半
折半
注意:

  1. (以上題爲例)low的第一次移動要移動到 mid+1,因爲mid原來坐在的位置,數據已經比較過一次了,可以直接跳到它的下一個。(同理:high=mid-1)
  2. 如何判斷沒有找到key?
    low > high 時就說明沒有找到。換句話說,循環條件就是 low<=high
int Search_Bin(int a[],int n,int key)
{
    int low = 1;
    int high = n;
    while(low<=high)
    {
        mid = (low+high)/2;
        if(key == a[mid])
            return mid;
        else if (key<a[mid])
            high = mid-1;
        else
            low = mid +1;
    }
    return 0;
}

折半查找的性能分析

折半查找的判定樹:
性能分析

  • 一般情況下,表長爲n的折半查找的判定樹的深度和含有n個結點的完全二叉樹的深度相同。
    所以:
    折半性能

索引查找(分塊查找)

  • 分塊查找的性能介於順序查找和折半查找。只用於分段有序的信息表。
  • 分段查找的核心思想:在建立順序表的同時,建立一個索引表。
    分塊
  • 可以看出索引表可以用折半查找,而基本表不可以。
  • 基本思想:首先根據索引表確定待查記錄的區間,然後再確定的主表區間採用順序查找。(索引思想是當前大數據處理方面常用的思想。)
  • 性能分析:
    分塊查找性能
    缺點:需要有輔助數組,且初始表要經過分塊排序。

三種查找方式的比較

查找方式 性能 適用條件
順序查找 ASL= (n+1)/2 或n+1,性能最差 亂序表
折半查找 ASL=(2log)n 或 (2log)n+!,性能最好 有序表
分塊查找 性能位於前兩者中間 分塊有序表

然而這三者都只適用於靜態查找。如果我們想在查找的同時,對一些記錄進行添加、刪除操作,就要使用下面的樹表。

樹表查找

二叉排序樹

定義

建立

查找

刪除

平衡二叉樹

散列查找

散列技術

散列函數設計

衝突處理

常用的散列函數

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