查找算法(未完待續(xù)......最近確實忙,有時間一定續(xù)上)

一、靜態(tài)查找:只查找給定的值,不做其他任何的操作,不改變表結(jié)構(gòu)和數(shù)據(jù)元素

1.查找某特定的關(guān)鍵字是否在表中(判斷性查找)
2.檢索某特定關(guān)鍵字的數(shù)據(jù)元素的各種屬性(檢索性查找)

(一)順序查找(待查找數(shù)據(jù)無序)

順序查找也叫線性查找,它的查找過程:從表中的第一個(最后一個)數(shù)據(jù)元素開始,逐個將給定值和數(shù)據(jù)元素的屬性進(jìn)行對比,如果兩個值相等,查找成功,直到查找到最后所有數(shù)據(jù)元素都不相等,則查找失敗。 示例代碼如下:

 /**
 順序查找(正序)

 @param a 待查找數(shù)組
 @param n 數(shù)組中元素個數(shù)
 @param key 給定值
 @return 目標(biāo)數(shù)據(jù)元素的在數(shù)組的下標(biāo),若為0則查找失敗
 */
int seq_search(int *a, int n, int key) {
    for (int i = 1; i < n; ++i) {
        if (key == a[i]) {
            return i;
        }
    }
    return 0;
}
                                  程序1.1.1

程序1.1.1是一個簡單的順序查找示例,這個實現(xiàn)是有改進(jìn)空間的,我們可以看到每次for循環(huán)都要進(jìn)行一次防止數(shù)組越界的比較 i < n,這是一個可優(yōu)化點,我們可以在查找方向的末端設(shè)置一個哨兵,這個哨兵是給定值,倘若程序在查找過程中已經(jīng)找到,那么返回的值為目標(biāo)數(shù)據(jù)元素在數(shù)組中的下標(biāo),否則,為我們設(shè)定的哨兵在數(shù)組的下標(biāo)

/**
 順序查找(正序)
 
 @param a 待查找數(shù)組
 @param n 數(shù)組中元素個數(shù)
 @param key 給定值
 @return 目標(biāo)數(shù)據(jù)元素的數(shù)組下標(biāo),若為n則查找失敗
 */
int seq_search2(int *a, int n, int key) {
    int i = 0;
    a[n] = key;
    while (a[i] != key) {
        i++;
    }
    return i;
}
                                  程序1.1.2

順序查找的時間復(fù)雜度:

  • 在查找成功的情況下:
    目標(biāo)元素在第一個位置,循環(huán)一次查找成功,時間復(fù)雜度為O(1)
    目標(biāo)元素在最后一個位置,循環(huán)n次查找成功,時間復(fù)雜度為O(n)
  • 失敗的情況下:
    程序1.1.1需要循環(huán)n次,時間復(fù)雜度為O(n)
    程序1.1.2需要循環(huán)n+1次,時間復(fù)雜度為O(n)

ASL = ∑ Pi * Ci(i = 1, 2, 3 .... n, 即將所有位置查找的概率與查找到該位置比較的次數(shù)乘積進(jìn)行累和
Pi:每個位置上的查獲找成功的概率是相同的為 1/n
Ci:查找成功的次數(shù)為(1 + 2 + 3 + ......+ n )= n * (n + 1) / 2
ASL:平均查找長度為:1/n * { n * (n + 1) / 2} = (n + 1) / 2

因此順序查找的時間復(fù)雜度為O(n)

(二)折半查找(待查找數(shù)據(jù)有序)

折半查找也叫二分查找使用折半查找的前提是帶查找的數(shù)據(jù)是有序的(從小到大),它的查找過程:取待查找數(shù)據(jù)的中間的一個數(shù)據(jù)元素與給定值行比較

  • 如果兩者相等,查找成功
  • 如果所取數(shù)據(jù)元素比給定值大,則在中間元素的左側(cè)繼續(xù)重復(fù)查找過程,直到查找成功或者失敗
  • 如果所取數(shù)據(jù)元素比給定值小,則在中間元素的右側(cè)繼續(xù)重復(fù)查找過程,直到查找成功或者失敗
/**
 折半查找
 
 @param a 待查找數(shù)組
 @param n 數(shù)組中元素個數(shù)
 @param key 給定值
 @return 目標(biāo)數(shù)據(jù)元素的數(shù)組下標(biāo),若為0則查找失敗
 */
int binary_search(int *a, int n, int key) {
    
    //數(shù)組的第一個元素的下標(biāo)
    int low = 0;
    
    //數(shù)組的最后一個元素的下標(biāo)(數(shù)組下標(biāo)從0開始,n為長度,因此最后一元素的下標(biāo)為0)
    int height = n - 1;
    
    //計算的出數(shù)組中間的數(shù)據(jù)元素的下標(biāo)
    int mid = (low + height) / 2;
    
    //只要待查找的區(qū)域的首部和尾部不相等
    //若是相等,意味著,收尾相接,只有一個元素
    while (low <= height) {
        
        //給定值key和數(shù)組中間的數(shù)據(jù)元素相等
        if (key == a[mid]) {
            
            //查找成功
            return a[mid];
            
        //給定值key比中間的數(shù)據(jù)元素大,則要繼續(xù)下一次查找
        } else if (key > a[mid]) {
            //下一次查找的區(qū)域改變?yōu)?中間值右側(cè)到數(shù)組末尾
            //此時需要改變low的值,進(jìn)而改變mid的值
            //low = mid + 1是因為,mid已經(jīng)取過了,比較過了
            low = mid + 1;
            
        //給定值key比中間的數(shù)據(jù)元素小,則要繼續(xù)下一次查找
        } else {
            //下一次查找的區(qū)域改變?yōu)?中間值左側(cè)到數(shù)組末尾
            //此時需要改變height的值,進(jìn)而改變mid的值
            //height = mid - 1是因為,mid已經(jīng)取過了,比較過了
            height = mid - 1;
        }
        
        //每一趟不成的查找都要重新計算mid的值,從而進(jìn)行下一次的折半查找
        mid = (low + height) / 2;
    }
    
    return 0;
}
二、動態(tài)查找:給定值,在查找過程中插入此數(shù)據(jù)元素不存在則插入給定值的數(shù)據(jù)元素,或者,刪除給定值所對應(yīng)的數(shù)據(jù)元素

1.查找時插入數(shù)據(jù)元素
2.查找時刪除數(shù)據(jù)元素

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容