常用查詢演算法

CSDN學院發表於2016-10-28

1. 順序查詢

1.1 演算法原理:

  順序查詢是在一個已知無(或有序)序佇列中找出與給定關鍵字相同的數的具體位置。原理是讓關鍵字與佇列中的數從第一個開始逐個比較,直到找出與給定關鍵字相同的數為止,它的缺點是效率低下。

1.2 演算法實現(Java):

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> sequenceSearch(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> des) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span> (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> i = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, len = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>.length; i < len; i++) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>[i] == des) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> i;
        }
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li></ul>

2. 二分查詢

2.1 演算法原理:

  二分查詢又稱折半查詢,優點是比較次數少,查詢速度快,平均效能好;其缺點是要求待查表為有序表,且插入刪除困難。因此,二分查詢方法適用於不經常變動而查詢頻繁的有序列表。其演算法原理如下: 
  首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。 
  重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。

2.2 演算法實現(Java):

<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> binarySearch(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>[] <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> des) {
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> low = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> high = <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>.length - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">while</span> (low <= high) {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> middle = (low + high) >> <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>[middle] == des) {
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> middle;
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">array</span>[middle] > des) {
            high = middle - <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        } <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">else</span> {
            low = middle + <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
        }
    }
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> -<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li></ul>

3. 分塊查詢

3.1 演算法原理:

  分塊查詢又稱索引順序查詢,是折半查詢和順序查詢的一種改進方法,折半查詢雖然具有很好的效能,但其前提條件時線性表順序儲存而且按照關鍵碼排序,這一前提條件在結點樹很大且表元素動態變化時是難以滿足的。而順序查詢可以解決表元素動態變化的要求,但查詢效率很低。如果既要保持對線性表的查詢具有較快的速度,又要能夠滿足表元素動態變化的要求,則可採用分塊查詢的方法。 
  分塊查詢的速度雖然不如折半查詢演算法,但比順序查詢演算法快得多,同時又不需要對全部節點進行排序。當節點很多且塊數很大時,對索引表可以採用折半查詢,這樣能夠進一步提高查詢的速度。 
  分塊查詢要求把一個大的線性表分解成若干塊,每塊中的節點可以任意存放,但塊與塊之間必須排序。假設是按關鍵碼值非遞減的,那麼這種塊與塊之間必須滿足已排序要求,實際上就是對於任意的i,第i塊中的所有節點的關鍵碼值都必須小於第i+1塊中的所有節點的關鍵碼值。此外,還要建立一個索引表,把每塊中的最大關鍵碼值作為索引表的關鍵碼值,按塊的順序存放到一個輔助陣列中,顯然這個輔助陣列是按關鍵碼值非遞減排序的。查詢時,首先在索引表中進行查詢,確定要找的節點所在的塊。由於索引表是排序的,因此,對索引表的查詢可以採用順序查詢或折半查詢;然後,在相應的塊中採用順序查詢,即可找到對應的節點。

4. 雜湊查詢

4.1 演算法原理:

  雜湊查詢是通過計算資料元素的儲存地址進行查詢的一種方法。雜湊查詢的操作步驟如下: 
  (1)用給定的雜湊函式構造雜湊表; 
  (2)根據選擇的衝突處理方法解決地址衝突; 
  (3)在雜湊表的基礎上執行雜湊查詢。 
  雜湊查詢的本質是先將資料對映成它的雜湊值。雜湊查詢的核心是構造一個雜湊函式,它將原來直觀、整潔的資料對映為看上去似乎是隨機的一些整數。 
  雜湊查詢的產生有這樣一種背景——有些資料本身是無法排序的(如影像),有些資料是很難比較的(如影像)。如果資料本身是無法排序的,就不能對它們進行比較查詢。如果資料是很難比較的,即使採用折半查詢,要比較的次數也是非常多的。因此,雜湊查詢並不查詢資料本身,而是先將資料對映為一個整數(它的雜湊值),並將雜湊值相同的資料存放在同一個位置——即以雜湊值為索引構造一個陣列。 
  在雜湊查詢的過程中,只需先將要查詢的資料對映為它的雜湊值,然後查詢具有這個雜湊值的資料,這就大大減少了查詢次數。

4.2 解決雜湊衝突:

  影響雜湊查詢效率的一個重要因素是雜湊函式本身。當兩個不同的資料元素的雜湊值相同時,就會發生衝突。為減少發生衝突的可能性,雜湊函式應該將資料儘可能分散地對映到雜湊表的每一個表項中。解決衝突的方法有以下兩種: 
  (1) 開放地址法 
  如果兩個資料元素的雜湊值相同,則在雜湊表中為後插入的資料元素另外選擇一個表項。 
  當程式查詢雜湊表時,如果沒有在第一個對應的雜湊表項中找到符合查詢要求的資料元素,程式就會繼續往後查詢,直到找到一個符合查詢要求的資料元素,或者遇到一個空的表項。 
  (2) 鏈地址法 
  將雜湊值相同的資料元素存放在一個連結串列中,在查詢雜湊表的過程中,當查詢到這個連結串列時,必須採用線性查詢方法。

相關文章