如何在域控中設定DNS反向解析
一、順序查詢
public int sequenceSearch(int[] a, int value){ for(int i = 0; i < a.length; i++){ if(a[i] == value) return i; } return -1; }
二、二分查詢
要求:元素必須是有序的。如果是無序的,則要先進行排序操作。
1. 使用迴圈實現
public int binarySearch2(int[] a, int value) { int low = 0, high = a.length - 1, mid;while (low <= high) { mid = (low + high) / 2; if (a[mid] == value) return mid; else if (a[mid] > value) high = mid - 1; else low = mid + 1; } return -1-low; //-1-low表示value應插入的位置? }
2. 使用遞迴實現
public int binarySearch(int[] a, int value, int low, int high) { int mid = (low + high) / 2; if (a[mid] == value) return mid; else if (a[mid] < value) return binarySearch(a, value, mid + 1, high); else return binarySearch(a, value, low, mid - 1); }
3. 二分查詢的變種:插值查詢
基本思想:基於二分查詢演算法,將查詢點的選擇改進為自適應選擇,可以提高查詢效率。它是二分查詢的改進版。
二分查詢:
mid = (low+high)/2 , 即 mid = low + (high-low)/2;
改進後:
mid = low + (high - low) * (key - a[low]) / (a[high] - a[low]);
前提條件:適合表長較大,而關鍵字分佈又比較均勻的查詢表。
public class InsertValueSearch {
public static void main(String[] args) {
int[] arr = {-4, -1, 0, 1, 2, 4, 5, 6, 7, 10};
System.out.println(insertValueSearch(arr, 1, 0, arr.length - 1));
}
public static int insertValueSearch(int[] arr, int key, int low, int high) {
if (low > high) {
return -1;
}
int mid = low + (high - low) * (key - arr[low]) / (arr[high] - arr[low]);
if (key < arr[mid]) {
return insertValueSearch(arr, key, low, mid - 1);
} else if (key > arr[mid]) {
return insertValueSearch(arr, key, mid + 1, high);
} else {
return mid;
}
}
}
三、斐波那契查詢
基本思想:斐波那契查詢是二分查詢的一種提升演算法,通過運用黃金比例的概念在數列中選擇查詢點進行查詢,提高查詢效率。注意同時屬於一種有序查詢演算法
public class FibonacciSearch { private static final int size = 20; public static void main(String[] args) { int[] arr = {-4, -1, 0, 1, 2, 4, 5, 6, 7, 10}; System.out.println(fibonacciSearch(arr, 7)); } public static int fibonacciSearch(int[] arr, int key) { int len = arr.length; int low = 0; int mid = 0; int high = len - 1; int n = 0; int[] f = getFib(); //找到等於或剛剛大於high的斐波那契值 while (len > f[n] - 1) { n++; } //建立一個長度為f[n]-1的臨時陣列,超出arr長度的部分用最後一個元素補齊 int[] temp = Arrays.copyOf(arr, f[n] - 1); for (int i = high + 1; i < temp.length; i++) { temp[i] = arr[high]; } System.out.println(Arrays.toString(temp)); while (low <= high) { //mid = low + f[n - 1] - 1 mid = low + f[n - 1] - 1; //f[n] = f[n - 1] + f[n - 2] //總 = 前 + 後 if (key < temp[mid]) { high = mid - 1; n -= 1; } else if (key > temp[mid]) { low = mid + 1; n -= 2; } else { if (mid <= high) { return mid; } else { return high; } } } return -1; } public static int[] getFib() { int[] f = new int[size]; f[0] = 1; f[1] = 1; for (int i = 2; i < size; i++) { f[i] = f[i - 1] + f[i - 2]; } return f; } }
四、二叉排序樹查詢
基本思想:二叉查詢樹是先對待查詢的資料進行生成樹,確保樹的左分支的值小於右分支的值,然後在就行和每個節點的父節點比較大小,查詢最適合的範圍。
注意:前提條件要首先建立樹。
二叉查詢樹或者是一棵空樹,特點如下:
1)若任意節點的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
2)若任意節點的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
3)任意節點的左、右子樹也分別為二叉查詢樹。
public class SearchBST { //全域性變數, 存放查詢到的關鍵字所在的父節點 static BinTree parentNode = new BinTree(); public static void main(String[] args) { //主要是表達查詢,所以手動構造一棵二叉排序樹 BinTree bt1 = new BinTree(); bt1.data = 62; BinTree bt2 = new BinTree(); bt1.lchild = bt2; bt2.data = 58; BinTree bt3 = new BinTree(); bt2.lchild = bt3; bt3.data = 47; BinTree bt4 = new BinTree(); bt3.lchild = bt4; bt4.data = 35; BinTree bt5 = new BinTree(); bt4.rchild = bt5; bt5.data = 37; BinTree bt6 = new BinTree(); bt3.rchild = bt6; bt6.data = 51; BinTree bt7 = new BinTree(); bt1.rchild = bt7; bt7.data = 88; BinTree bt8 = new BinTree(); bt7.lchild = bt8; bt8.data = 73; BinTree bt9 = new BinTree(); bt7.rchild = bt9; bt9.data = 99; BinTree bt10 = new BinTree(); bt9.lchild = bt10; bt10.data = 93; boolean search = searchBST(bt1, 88, null); System.out.println(search == true ? "查詢成功:" + parentNode.data : "查詢失敗!"); } /** * 二叉排序樹 * * @param bt 待查詢二叉排序樹 * @param key 查詢關鍵字 * @param parent 指向bt的雙親,其初始呼叫值為null * @return 查詢關鍵字key成功 返回true,並把樹結點賦值給全域性變數result,查詢失敗,返回false */ public static boolean searchBST(BinTree bt, int key, BinTree parent) { // 樹節點不存在,返回 if (null == bt || 0 == bt.data) { parentNode = parent; return false; } else if (key == bt.data) {// 查詢成功 parentNode = bt; return true; } else if (key < bt.data) {// 關鍵字小於根節點則查詢左子樹 return searchBST(bt.lchild, key, bt); } else {// 關鍵字大於根節點則查詢右子樹 return searchBST(bt.rchild, key, bt); } } /** * 二叉樹 資料結構 */ private static class BinTree { int data; BinTree lchild; BinTree rchild; } }
五、雜湊表查詢
1. 定義
雜湊表查詢又叫散列表查詢,通過查詢關鍵字,不需要比較就可以獲得需要記錄的儲存位置。它是通過記錄的儲存位置和它的關鍵字之間建立一個確定的對應關係f,使得每個關鍵字key對應一個儲存位置f(key)。
即:儲存位置=f(關鍵字),其中f為雜湊函式。
2. 雜湊函式的構造方法
(1). 直接定址法(取關鍵字的某個線性函式值為雜湊地址)
例:f(key)= a*key + b (其中a,b均為常數)
(2). 數字分析法(通過關鍵字的整體情況來判斷去關鍵字的某一段或者某一種形式):
原則:儘量選擇關鍵字出現隨機且相互獨立的區段。
(3). 除留餘數法
這是最為常用的構造雜湊函式的方法,對於雜湊表長度為m的雜湊函式為:
f(key)=key mod p (p<=m)通常p為小於或者等於表長的最小質數(只能被1和其自身整除的數)
3. 解決衝突的方法
(1). 開放定址法:
1):線性探測再雜湊:即從衝突的地址開始往後找,直至找到‘空’的雜湊地址。
2):二次探測再雜湊:一次取1的二次方,-1的二次方,2的二次方,-2的二次方……讓當前衝突的雜湊地址與這些數字一次相加知道找到‘空地址’,其實我們可以看做在衝突的地方兩邊波動並逐漸遠離。
3):偽隨機數序列: 使用隨機函式計算
(2). 再雜湊法:H = R(H(key)):即在同義詞產生地址衝突時通過另一個雜湊函式計算雜湊地址。
(3). 鏈地址法:建立一個連結串列,將所有關鍵字為同義詞的記錄儲存在此線性表中。
public class HashTableSearch { public static void main(String[] args) { int[] arr = {1, 3, 5, 65, 6, 34, 67, 343, 56}; System.out.println(hashSearch(arr,34)); System.out.println(hashSearch(arr,100)); } /*** * * 雜湊結點 */ private static class Node { int key; // 連結串列中的鍵 Node next; // 下一個同義詞 } /*** * 在雜湊表中查詢關鍵字key * @param data * @param key * @return */ public static boolean hashSearch(int[] data, int key) { int p = 1; // 尋找小於或等於最接近表長的素數 for (int i = data.length; i > 1; i--) { if (isPrimes(i)) { p = i; break; } } // 構建雜湊表 Node[] hashtable = createHashTable(data, p); // 查詢key是否在雜湊表中 int k = key % p; Node cur = hashtable[k]; while (cur != null && cur.key != key) { cur = cur.next; } if (cur == null) { return false; } else { return true; } } /*** * 用求餘,連結串列法構建雜湊表 * @param data * @param p * @return */ public static Node[] createHashTable(int[] data, int p) { Node[] hashtable = new Node[p]; int k; //雜湊函式計算的單元地址 for (int i = 0; i < data.length; i++) { Node node = new Node(); node.key = data[i]; k = data[i] % p; if (hashtable[k] == null) { hashtable[k] = node; } else { Node current = hashtable[k]; while (current.next != null) { current = current.next; } current.next = node; } } return hashtable; } /*** * 除餘法構建雜湊函式 用連結串列法解決雜湊衝突 * @param n * @return */ public static boolean isPrimes(int n) { for (int i = 2; i <= Math.sqrt(n); i++) { if (n % i == 0) { return false; } } return true; } }
參考:
https://xie.infoq.cn/article/996cf8899930ae467cc790035
https://blog.csdn.net/smile_from_2015/article/details/72190562