java實現常見查找算法

電腦雜談  發布時間:2019-06-18 13:09:45  來源:網絡整理

樹和二叉樹的轉換_c 二叉排序樹_排序二叉樹的刪除

查找

查找(Searching)就是根據給定的某個值,在查找表中確定一個其關鍵字等于給定值的數據元素(或記錄)。

在互聯網上查找信息是我們的家常便飯。所有這些需要被查的數據所在的集合,我們給它一個統稱叫查找表。

查找表(Search Table)是由同一類型的數據元素(或記錄)構成的集合。

關鍵字(Key)是數據元素中某個數據項的值,又稱為鍵值,用它可以標識一個數據元素。也可以標識一個記錄的某個數據項(字段) ,我們稱為關鍵碼。

若此關鍵字可以唯一地標識一個記錄,則稱此關鍵字為主關鍵字 (Primary Key)。

注意這也就意味著,對不同的記錄,其主關鍵字均不相同。主關鍵字所在的數據項稱為主關鍵碼。

那么對于那些可以識別多個數據元素(或記錄)的關鍵字,我們稱為次關鍵字(Secondary Key)。次關鍵字也可以理解為是不以唯一標識一個數據元素(或記錄)的關鍵字,它對應的數據項就是次關鍵碼。

查找表按照操作方式來分有兩大種:靜態查找表和動態查找表。

靜態查找表(Static Search Table) :只作查找操作的查找表。它的主要操作有:

( 1 ) 查詢某個"特定的"數據元素是否在查找表中。

( 2 ) 檢索某個"特定的"數據元索和各種屬性。

按照我們大多數人的理解,查找,當然是在已經有的數據中找到我們需要的。靜態查找就是在干這樣的事情,不過,現實中還有存在這樣的應用:查找的目的不僅僅只是查找,還可能邊查找邊作其它操作。

動態查找表(Dynamic Search Table): 在查找過程中同時插入查找表中不存在的數據元素,或者從查找表中刪除已經存在的某個數據元素。顯然動態查找表的操作就是兩個:

( 1 ) 查找時插入數據元素。

( 2 ) 查找時刪除數據元素。

為了提高查找的效率 ,我們需要專門為查找操作設置數據結構,這種面向查找操作的數據結構稱為查找結構。

從邏輯上來說,查找所基于的數據結構是集合,集合中的記錄之間沒有本質關系。可是要想獲得較高的查找性能,我們就不得不改變數據元素之間的關系,在存儲時可以將查找集合組織成表、樹等結構。

例如,對于靜態查找表來說,我們不妨應用線性表結構來組織數據,這樣可以使用順序查找算法,如果再對主關鍵字排序,則可以應用折半查找等技術進行高效的查找。

如果是需要動態查找,則會復雜一些,可以考慮二叉排序樹的查找技術。另外,還可以用散列表結構來解決一些查找問題,這些技術都將在后面的講解中說明。

順序查找 (Sequential Search) 又叫線性查找,是最基本的查找技術, 它的查找過程是:從表中第一個(或最后一個)記錄開始,逐個進行記錄的關鍵字和給定值比較,若某個記錄的關鍵字和給定值相等,則查找成功,找到所查的記錄;如果直到最后一個(或第一個)記錄,其關鍵字和給定值比較都不等時,則表中沒有所查的記錄,查找不成功 。

順序查找的算法實現如下。

/**
 * 順序查找
 * 
 * @param a
 *            數組
 * @param key
 *            待查找關鍵字
 * @return 關鍵字下標
 */
public static int sequentialSearch(int[] a, int key) {
	for (int i = 0; i < a.length; i++) {
		if (a[i] == key)
			return i;
	}
	return -1;
}

這段代碼非常簡單,就是在數組a中查看有沒有關鍵字key,當你需要查找復雜表結構的記錄時,只需要把數組a與關鍵字key定義成你需要的表結構和數據類型即可。

到這里并非足夠完美,因為每次循環時都需要對i是否越界,即是否于等于n作判斷。事實上,還可以有更好一點的辦法,設置一個哨兵,可以解決不需要每次讓i與n作比較。看下面的改進后的順序查找算法代碼。

/**
 * 有哨兵順序查找
 * 
 * @param a
 *            數組(下標為0存放哨兵元素)
 * @param key
 *            待查詢關鍵字
 * @return 關鍵字下標 返回0 則未找到
 */
public static int sequentialSearch2(int[] a, int key) {
	int index = a.length - 1;
	a[0] = key;// 將下標為0的數組元素設置為哨兵
	while (a[index] != key) {
		index--;
	}
	return index;
}

這種在查找方向的盡頭放置"哨兵"免去了在查找過程中每一次比較后都要判斷查找位置是否越界的技巧,看似與原先差別不大,但在總數據較多時,效率提高很大,是非常好的編碼技巧。當然,"哨兵"也不一定就一定要在數組開始,也可以在末端。

對于這種順序查找算法來說,查找成功最好的情況就是在第一個位置就找到了,算法時間復雜度為O(1),最壞的情況是在最后一位置才找到,需要n次比較,時間復雜度為O(n),當查找不成功時,需要n+1次比較,時間復雜度為O(n)。我們之前推導過,關鍵字在任何一位置的概率是相同的,所以平均查找次數為(n+1)/2 ,所以最終時間復雜度還是O(n)。

很顯然,順序查找技術是有很大缺點的,n很大時,查找效率極為低下,不過優點也是有的,這個算法非常簡單,對靜態查找表的記錄沒有任何要求,在一些型數據的查找時,是可以適用的。

后面的14 20其實是多余的,因為碰到的概率是千分之一,但是為了防止這種概率事件的發生,所以把14 20可以帶上,并不是說14 20中了就賺錢了,而是說,如果碰到這種錯誤周期集中的極端現象時,我們不要著急,因為概率決定了我們的命中率是10中7 所以,前面錯的多,后面必然對的就多,不然是沒法回歸均衡的,后面既然對的多,那么14 或者20我們一直平買,很快就把前面虧的賺回來了,然后就可以回到1倍從新開始了,這個你只要實戰操作幾天就知道了。2、為什么要把2個放在3個的前面,4個放在3個的后面(2個比3個少1個,排在3個的前面,4個比3個多1個,排在4個的后面)。讓寶寶將兩手放在身體前面和后面,或把玩具放在身前身后,讓孩子形成前后概念,然后擴大到日常生活中,“你看那棵樹,是在房子前面,還是后面。

一個線性表有序時,對于查找總是很有幫助的。

折半查找(Binary Search)技術,又稱為二分查找。它的前提是線性表中的記錄必須是關鍵碼有序(通常從到大有序) ,線性表必須采用順序存儲。折半查找的基本思想是:在有序表中,取中間記錄作為比較對象,若給定值與中間記錄的關鍵字相等,則查找成功;若給定值于中間記錄的關鍵字,則在中間記錄的左半區繼續查找;若給定值大于中間記錄的關鍵字,則在中間記錄的右半區繼續查找。不斷重復上 述過程,直到查找成功,或所有查找區域無記錄,查找失敗為止。

我們來看折半查找的算法是如何工作的。

/**
 * 折半查找
 * 
 * @param a
 *            數組
 * @param key
 *            待查找關鍵字
 * @return 返回折半下標, -1表示不存在該關鍵字
 */
public static int binarySearch(int[] a, int key) {
	int low, mid, high;
	low = 0;// 最下標
	high = a.length - 1;// 最大標
	while (low <= high) {
		mid = (high + low) / 2;// 折半下標
		if (key > a[mid]) {
			low = mid + 1; // 關鍵字比 折半值 大,則最下標 調成 折半下標的下一位
		} else if (key < a[mid]) {
			high = mid - 1;// 關鍵字比 折半值 ,則最大下標 調成 折半下標的前一位
		} else {
			return mid; // 當 key == a[mid] 返回 折半下標
		}
	}
	return -1;
}

針對異構環境 中的效率 0.85 023 o.24 o.42調度這一復雜 問題,以fork.join這類特殊而重要 的任務圖為時間復雜度 df1 d v1 df 0 vlog們研究對象,本文提 出一個具有高的加速 比的貪心調度算法一tds算法將join任務 的每個父任務分別調度至不 同處理 htgsfj算法,該算法借鑒同構環境經典算法 的相關策略,同機 ,不僅可能失去生成較短調度的機會 ,而且忽視 了異構環境 時又充分考慮異構環境的特點,可 以應用至任意 fork.join任的特點,使得調度長度很長、處理機個數很多,共使用 了5個 務 圖并產生有效的調度 ,其時間復雜度為d v2 ,其 中,v表示任處理機 。純屬復習或者說再學一遍tarjan算法,本題的主要算法就是tarjan+縮點,對于兩個子問題的答案,根據解題:強連通縮點為拓撲圖后,設入度為0點數為r,出度為0點數為c,則task 1的答案就是r,這個很好理解。arm和x86功耗的差別一直是個很熱的話題.arm可以做的很低,甚至1瓦都不到.而x86服務器的芯片可以達到100-200瓦,就算是嵌入式處理器 atom系列也需要幾瓦.很說這是指令集的關系.arm采用精簡指令集,x86采用復雜指令集,前者每條功能簡單,單挑指令耗電低.而后者每條指令復 雜,單個指令耗電高.但是這種解釋很模糊.如果大家都做同樣的事情,完成一個大功能,精簡指令集需要指令較多,而復雜指令集需要指令少,加起來到底誰耗電 多呢.還有,現在處理器普遍采用微指令,大的指令會被拆分成更的指令,以達到更高的流水線效率.簡單指令集的單條微指令和復雜指令集的單條微指令相比的 話,情況就更復雜.我手頭沒有關于比較的具體數據,但是至少前文所列出關于功耗和指令集相關的解釋不是很有說服力.。

首先,我們將數組的查找過程繪制成一棵二叉樹,如果查找的關鍵字不是中間記錄的話,折半查找等于是把靜態有序

否則利用中間位置記錄將表分成前、后兩個子表,如果中間位置記錄的關鍵字大于查找關鍵字,則進一步查找前一子表,否則進一步查找后一子表。因此, 在磁盤上進行查找的次數、即待查找關鍵字所在結點在b- 樹上的層次樹, 是決定b樹查找效率的首要因素。首先,無索引的表,查詢時,是按照順序存續的方法掃描每個記錄來查找符合條件的記錄,這樣效率十分低下,舉個例子,如果我們將字典的漢字隨即打亂,沒有前面的按照拼音或者部首查詢,那么我們想找一個字,按照順序的方式去一頁頁的找,這樣效率有多底,大家可以想象。

堆排序是一種樹形選擇排序,在排序過程中,將a[n]看成是完全二叉樹的順序存儲結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關系來選擇最的元素。ps: 樹的路徑長度是從樹根到樹中每一結點的路徑長度之和.在結點數目相同的二叉樹中,完全二叉樹的路徑長度最短.。9.完全二叉樹的順序存儲方案,是指將完全二叉樹的結點從上至下、從左至右一次存放到一個順序結構的數組中。

叉樹,但同樣相同的推導可以得出,最壞情況是查找到關鍵字或查找失敗的次數為[log2n]+1,最好的情況是1次。

因此最終我們折半算法的時間復雜度為O(logn),它顯然遠遠好于順序查找的O(n)時間復雜度了。

8 查找結構:符號表,二叉查找樹,二叉查找樹的查找、插入和刪除操作,avl樹,高度平衡,ll, lr, rr, rl 旋轉, 插入算法,時間復雜性分析,b樹,m叉查找樹,m叉查找樹的查找,b樹的定義和性質,b樹的插入操作,b樹的刪除操作,靜態散列,散列表,散列函數,溢出處理,開放尋址,鏈接。 3.熟練掌握單鏈表的插入、刪除和查詢算法...元素刪除、元素查找、測表空、求表長等單 鏈表的基本操作算法有了進一步的了解...。(2) 線性表adt順序存儲實現中的創建、查找、插入和刪除等基本操作及相關算法,線性表adt鏈式存儲實現中單鏈表、循環鏈表和雙向鏈表的創建、查找、插入和刪除等基本操作及相關算法。


本文來自電腦雜談,轉載請注明本文網址:
http://www.rtcsln.tw/a/jisuanjixue/article-106859-1.html

相關閱讀
發表評論  請自覺遵守互聯網相關的政策法規,嚴禁發布、暴力、反動的言論

  • 楊亞娟
    楊亞娟

    就只說抗戰神劇就夠了

熱點圖片
拼命載入中...
黑龙江快乐十分开奖直播