15.有序表尋找與線索索引尋找,15線索索引

來源:互聯網
上載者:User

15.有序表尋找與線索索引尋找,15線索索引
轉載請表明出處:http://blog.csdn.net/u012637501
一、有序表尋找1.折半尋找/二分尋找演算法(1)基本思想:在順序儲存的有序表中,取中間紀錄(a[mid]=key)作為比較對象,若給定值與中間紀錄的關鍵字相等,則尋找成功;若給定值小於中間紀錄的關鍵字,則在中間紀錄的左半區繼續尋找;若給定值大於中間紀錄的關鍵字,則在中間紀錄的右半邊。不斷重複上述過程,直到尋找成功,或所有尋找地區無記錄,尋找失敗為止。(2)使用條件:線性表中的紀錄是關鍵碼有序的(通常是從小到大有序),線性表必須採用順序儲存,即有序表順序儲存。(3)演算法實現

/*折半尋找 *    a為線性表數組,n為資料元素總個數,key為要尋找的關索引值*/int Binary_Search(int *a,int n,int key){    int low,high,mid;    low=1;                    //定義最低下標為紀錄首位    high=n;    while(low<=high)    {        mid=(low+high)/2;    //折半(取整)        if(key<a[mid])            //若尋找值比中值小                    high=mid-1;    //最高下標調整到中位小一偉        else if(key>a[mid])    //若尋找值比中值大                    low=mid+1;    //最低下標調整到中位下標大一位        else                    return mid;    //若相等則說明Mid即為尋找到的位置,返回該位置地址    }    return 0;}
(4)舉例    假設有一有序表a={0,1,16,24,35,47,59,62,73,88,99},n=10,key=62。即除0下標外共10個數字,對它進行尋找是否存在62這個數。a.尋找步驟:第一步:.a[mid]=a[5]=47<key,則low=mid+1=6,此時,mid=(6+10)=8
第二步:a[mid]=a[8]=73>key,則high=mid-1=7,此時,mid=(6+7)/2=6
第三步:a[mid]=a[6]=59<key,則low=mid+1=7,此時,mid=(low+high)=(7+7)/2=7
第四步:a[mid]=a[7]=key,尋找成功。b.時間複雜度分析    下面我們將這個數組的尋找過程繪製成一棵二叉樹如下:    由二叉樹的性質4:"具有n個結點的完全二叉樹的深度為[log2^n]+1",可知在最壞情況下尋找到關鍵字或尋找失敗的次數為[log2^n]+1,最好情況為1次。相比於順序尋找的時間複雜度O(n),折半演算法的時間複雜度為O(logn),顯然效率高很多。
2.插值尋找演算法    在有序表尋找中,雖然折半尋找比順序尋找的查詢效率提高了很多,但有些時候折半還是存在比較大的局限性。比如要在取值範圍0~100000之間100個元素從小到大均勻分布的資料中尋找5,我們自然會考慮從數組下標較小的開始尋找,而不是從中間開始。(1)插值尋找法    插值尋找是在折半尋找演算法的改進,為另一種有序表尋找演算法。插值尋找(Interpolation Search)是根據要尋找的關鍵字key與尋找表中最大最小紀錄的關鍵字比較後的尋找方法,其核心就在於插值的計算公式(key-a[low])/(a[high]-a[low]),即mid=low+(key-a[low])/(a[high]-a[low])。(2)適用條件:表長較大且關鍵字分布比較均勻的有序表。(3)時間複雜度:O(logn)(4)舉例:    如上例中a={0,1,16,24,35,47,59,62,73,88,99},我們要查詢關鍵字16。如果使用折半尋找(mid=(low+high)/2),需要尋找4次;如果使用插值尋找(mid=low+(key-a[low])/(a[high]-a[low])~=2),即只需兩次。 3.斐波那契尋找(1)斐波那契數列    斐波那契數列描述的是兔子的繁殖問題,這個數列有個十分明顯的特點:前面相鄰兩項之和,構成了後一項。其數學模型為:         | 0,當n=0時,其中n為月個數F(n)=| 1,當n=1時         |F(n-1)+F(n-2),當n>1。其中n為經曆的月個數,F(n)為第n個月時兔子的數量。
(2)演算法實現
int Fibonacci_Search(int *a,int n,int key){    int low,high,mid,i,k;    low=1;                    //定義最低下標為紀錄首位    high=n;                    //定義最高下標為紀錄未位    k=0;    while(n>F[k]-1)            k++;    for(i=n;i<F[k]-1;i++)        //將不滿的數值補全            a[i]=a[n];    while(low<=high)    {            mid=low+F[k-1]-1;            if(key<a[mid])            {                    high=mid-1;                    k=k-1;            }            else if(key>a[mid])    //若尋找紀錄大於當前分隔紀錄            {                    low=mid+1;        //最低下標調整到分隔下標mid+1處                    k=k-2;                //斐波那契數列下標減兩位            }            else            {                    if(mid<=n)                                return mid;        //若相等則說明mid即為尋找的位置                    else                                return n;            //若mid>n說明是補全數值,返回n            }    }    return 0;}
二、線性索引尋找    資料結構的最終目的就是提高資料的處理速度,索引是為了加快尋找速度而設計的一種資料結構。索引就是把一個關鍵字與它對應的紀錄相關聯的過程,一個索引由若干個索引項目構成,每個索引項目至少包含關鍵字和其對應的紀錄在儲存空間中的位置等資訊。索引技術是組織大型資料庫以及磁碟檔案的一種重要技術。索引按照結構可以分為線性索引、樹形索引和多級索引。所謂線性索引就是將索引項目集合組織為線性結構,也成索引表。 1.稠密索引    稠密索引就是指線上性索引中,將資料集中的每個紀錄對應一個索引項目。對於稠密索引這個線索表而言,索引項目一定是按照關鍵碼有序的排列。注意:索引表有序,即當我們要尋找關鍵字時,可以用到折半、插值、斐波那契等有序尋找演算法,大大提高了效率。如,假如要尋找的關鍵字是18的紀錄,從右側的資料表中尋找,則只能順序尋找(需要6次);從左側索引表中尋找,則只需兩次折半尋找就可以得到18對應的指標。可見,線性索引尋找目的就是將資料從無序變為有序,進而使用有序尋找演算法提供效率。
2.分塊索引    稠密索引因為索引項目與資料集的紀錄個數相同,所以空間代價很大。為了減少索引項目的個數,我們可以資料集進行分塊,使其分塊有序,然後再對每一塊建立一個索引項目,從而減少索引項目的個數。(1)分塊有序原則    分塊有序,即把資料集的紀錄分成可若干塊,並且這些快需要滿足兩個條件:        ★塊內無序,即每一塊內的紀錄不要求有序;        ★塊間有序,如第二塊所有紀錄的關鍵字均要大於第一塊中所有紀錄的關鍵字......;(2)分塊索引:對於分塊有序的資料集,將每塊對應一個索引項目,這種索引方法叫做分塊索引。其中,分塊索引的索引項目結構分三個資料項目:        ★最大關鍵碼:用於儲存對應塊中的最大關鍵字,目的是使得在它之後的下一塊的最小關鍵字也能比這一塊最大的關鍵字要大;        ★塊長:儲存了塊中的紀錄個數,以便於迴圈時使用;        ★塊首指標:用於指向塊首資料元素的指標,便於開始對這一塊中紀錄進行遍曆。
(3)分塊索引表的尋找過程第一步:在分塊索引表中尋找要查的關鍵字所在的塊;第二步:根據塊首指標找到相應的塊,並在塊中順序尋找關鍵碼(塊中紀錄一般為無序)。(4)分塊索引的平均尋找長度    設n個紀錄的資料集被平均分成m塊,每個塊中有t條紀錄,顯然n=m*t,或者說m=n/t。根據最好域最差的等機率原則:    Lb為尋找索引表的平均尋找長度=(m+1)/2;    Lw為尋找某個紀錄的平均尋找長度=(t+1)/2; 可知,一次分塊索引尋找的平均尋找長度為:ASLw=Lb+Lw=(m+1)/2+ (t+1)/2=(m+t)/2+1=(n/t+t)/2+1.即平均長度不僅僅取決於資料集的總記錄數n,還和每一塊的紀錄個數t相關。    又n=m*t,ASLw=[(n/t+t)/2+1]>=[(n+t^2)/t]/2+1=[(m*t+t*t)/t]/2+1,假入m=t->t=√n,即分的塊數m與塊中的記錄數t相同,ASLw=√n +1時,為最好情況。O(n)<O(√n )<O(logn). 3.倒排索引    倒排索引源於實際應用中需要根據屬性(或欄位、次關鍵碼)的值來尋找紀錄。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.