常見的查找算法(六):分塊查找


  分塊查找又稱索引順序查找,它是順序查找的一種改進方法

  算法流程:

  • 先選取各塊中的最大關鍵字構成一個索引表
  • 查找分兩個部分:先對索引表進行二分查找順序查找,以確定待查記錄哪一塊中;然后,在已確定的塊中用順序法進行查找。

  注:算法的思想是將n個數據元素"按塊有序"划分為m塊(m ≤ n)。每一塊中的結點不必有序,但塊與塊之間必須"按塊有序",每個塊內的的最大元素小於下一塊所有元素的任意一個值

  所以,給定一個待查找key,在查找這個key值位置時會先去索引表中利用順序查找或者二分查找來找出這個key所在塊的索引開始位置,然后再根據所在塊的索引開始位置開始查找這個key所在的具體位置。

  下面給出一段分塊查找的代碼,其思想和上面描述的一樣,都是通過索引表來找key的位置。

  先給出主表索引表

 1     // 主表,size=30
 2     static int[] mainList = new int[]{
 3             101, 102, 103, 104, 105, 0, 0, 0, 0, 0,
 4             201, 202, 203, 204, 0, 0, 0, 0, 0, 0,
 5             301, 302, 303, 0, 0, 0, 0, 0, 0, 0
 6     };
 7 
 8     // 索引表
 9     static IndexItem[] indexItemList = new IndexItem[]{
10             new IndexItem(1, 0, 5),
11             new IndexItem(2, 10, 4),
12             new IndexItem(3, 20, 3)
13     };

  索引表類:

    static class IndexItem {
        public int index; //值比較的索引 public int start; //開始位置 public int length;//塊元素長度(非空) public IndexItem(int index, int start, int length) {
            this.index = index;
            this.start = start;
            this.length = length;
        }

        //... getter and setter
    }

  索引查找算法:

 1     public static int indexSearch(int key) {
 2         IndexItem indexItem = null;
 3 
 4         //建立索引規則
 5         int index = key / 100;
 6 
 7         //遍歷索引表
 8         for(int i = 0;i < indexItemList.length; i++) {
 9             //找到索引項
10             if(indexItemList[i].index == index) {
11                 indexItem = indexItemList[i];
12                 break;
13             }
14         }
15 
16         //索引表中不存在該索引項
17         if(indexItem == null)
18             return -1;
19 
20         //根據索引項,在主表中查找
21         for(int i = indexItem.start; i < indexItem.start + indexItem.length; i++) {
22             if(mainList[i] == key)
23                 return i;
24         }
25 
26         return -1;
27     }

  時間復雜度分析:先按二分查找去找key在索引表為大概位置(所給出代碼是順序查找),然后在主表中的可能所在塊的位置開始按順序查找,所以時間復雜度為O(log₂(m)+N/m),m為分塊的數量,N為主表元素的數量,N/m 就是每塊內元素的數量。

  分塊查找的插入算法:

 1     /**
 2      * 插入數據
 3      *
 4      * @param key 要插入的值
 5      * @return true表示插入成功,false表示插入失敗
 6      */
 7     public static boolean insert(int key) {
 8         IndexItem item = null;
 9 
10         // 建立索引規則
11         int index = key / 100;
12         int i = 0;
13         // 遍歷索引表,找到對應的索引項
14         for (i = 0; i < indexItemList.length; i++) {
15             if (indexItemList[i].index == index) {
16                 item = indexItemList[i];
17                 break;
18             }
19         }
20         // 索引表中不存在該索引項
21         if (item == null) {
22             return false;
23         }
24 
25         // 根據索引項將值插入到主表中
26         mainList[item.start + item.length] = key;
27         // 更新索引表
28         indexItemList[i].length++;
29 
30         return true;
31     }

  打印主表的函數:

 1     /**
 2      * 遍歷打印
 3      */
 4     public static void display(int[] list) {
 5         System.out.println("******** 展示開始 ********");
 6         if (list != null && list.length > 0) {
 7             for (int i = 0; i < list.length; i++) {
 8                 System.out.print(list[i] + " ");
 9                 if ((i + 1) % 10 == 0) {
10                     System.out.println("");
11                 }
12             }
13         }
14         System.out.println("******** 展示結束 ********");
15     }

  測試代碼:

 1     public static void main(String[] args) {
 2         System.out.println("******** 索引查找 ********");
 3         System.out.println("");
 4         System.out.println("原始數據:");
 5         display(mainList);
 6         System.out.println("");
 7 
 8         //分塊查找
 9         int key = 203;
10         System.out.println("元素" + key + "列表中的位置為:" + indexSearch(key) + "\n");
11 
12         //按規則插入數據並查找
13         int value = 106;
14         System.out.println("插入數據:" + value);
15         
16         // 插入成功,查找插入位置
17         if (insert(value)) {
18             System.out.println("插入后的主表:");
19             display(mainList);
20             System.out.println("");
21 
22             System.out.println("元素" + value + "在列表中的位置為:" + indexSearch(value));
23         }
24     }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM