手把手教你用java實現資料結構(五)-----查詢(二分法),遞迴(斐波那契數列,漢諾塔)演算法

Lmobject發表於2019-12-13

演算法對於程式設計師的要求是相當的嚴格,下面我們們就來聊聊面試最常見的演算法吧!!!

1.線性查詢演算法

此演算法為一般查詢演算法,時間複雜度為n,後期可以通過二分法查詢演算法優化

示例程式碼:

package com.yueqian.shujujiegou;

import javax.swing.plaf.FontUIResource;

/**
 * 資料結構------------線性查詢演算法
 * @author LinChi
 *
 */
public class Select_SuanFa {
	public static void main(String[] args) {
		//目標陣列
		int[] arr = new int[] {1,2,3,4,5,6,7,8,9};
		//目標元素
		int target = 7;
		//元素下標
		int index = -1;
		//迴圈遍歷
		for(int i = 0;i<arr.length;i++) {
			if(arr[i] == target) {
				index = i;
				break;
			}
		}
		System.out.println("查詢到"+target+"元素的下標:"+index);
	}
}
複製程式碼

2、二分法查詢演算法

最壞情況時間複雜度為 O(log2n)

手把手教你用java實現資料結構(五)-----查詢(二分法),遞迴(斐波那契數列,漢諾塔)演算法
最好情況時間複雜度為O(1)

手把手教你用java實現資料結構(五)-----查詢(二分法),遞迴(斐波那契數列,漢諾塔)演算法
演算法思想:

設定開始位置start,結束位置end,以及中間位置 mid=(end+start)/2,

如果arr[index]=mid,返回mid

如果arr[index]>mid,從後半段查詢,將start設定為mid+1

如果arr[index]<mid,從後半段查詢,將end設定為mid-1

如果start>end,返回-1,說明所查元素不存在

完整程式碼:

package com.yueqian.shujujiegou;

import java.util.Arrays;

/**
 * 資料結構---------二分法查詢
 * @author LinChi
 *
 */
public class Select1_SuanFa2 {
	public static void main(String[] args) {
		System.out.println(select(44));
	}
	public static int select(int target) {
		//定義陣列
		int[] arr = {21,32,36,44,45,36,47,38,29};
		//定義初始位置
		int start = 0;
		//定義結束位置
		int end = arr.length-1;
		//定義中間位置
		int mid = (start+end)/2;
		while(true) {
			//如果沒有這個元素,則start>=end,返回-1
			if(start>end) {
		 	return -1;
			}
			//判斷是否和中間位置元素值相等
			if(arr[mid] == target) {
				//將中間位置的索引賦值給目標位置
				return mid;
			}else {
				if(arr[mid] > target) {
					//將end位置設定為中間位置減一
					end = mid-1;
				}else {
					//將start位置設定為中間位置加1
					start = mid+1;
				}
				//取出新的中間位置(別忘記了)
				mid = (start+end)/2;
			}
		}
				
	}
    
}
複製程式碼

3、遞迴演算法

斐波那契數列 :0 1 1 2 3 5 8 13 21 ... n

遞迴實現

    //遞迴實現  (時間複雜度為 2的n次方)  n比較大時耗時太長
	public static int diGui(int n) {
		//先判斷是否為0或1
		if(n <= 2) {
			return 1;
		}else {
			return diGui(n-2)+diGui(n-1);
		}
		
	}
複製程式碼

for迴圈優化實現

//使用for迴圈優化這個遞迴 (時間複雜度為n)  此演算法效能比遞迴演算法效能高很多
	public static int xunHuan(int n) {
		//定義第一個數
		int first = 0;
		//定義第二個數
		int second = 1;
		for(int i = 0;i<n-1;i++) {
			//替換操作
			int sum = first+second;
			first = second;
			second = sum;
		}
		return second;
	}
複製程式碼

面試題: 有一對兔子,從出生後第三個月起,每個月都生一對兔子,小兔子長到3個月後,又生一對兔子,假如兔子都不死,問第7個月總共有多少對兔子?

1月 2月 3月 4月 5月 6月 7月

1對 1對 2對 3對 5對 8對 13對(斐波那契數列)

遞迴實現(時間複雜度為2的N次方)

	//生兔子問題
	public int birthRabbit(int month){
		if(month == 1 || month == 2) {
			return 1;
		} else {
			return birthRabbit(month - 1) + birthRabbit(month - 2);
		}
	}
複製程式碼

for迴圈優化(時間複雜度為N)

//使用for迴圈遍歷
	public static int add1(int n) {
		//定義第一個數
		int first = 1;
		int second = 1;
		for(int i = 1;i<n-1;i++) {
			int sum = first+second;
			first = second;
			second = sum;
		}
		return second;
	}
複製程式碼

面試題: 在你面前有一個n階的樓梯,你一步只能上1階或2階。請問,當N=11時,你可以採用多少種不同的方式爬完這個樓梯

手把手教你用java實現資料結構(五)-----查詢(二分法),遞迴(斐波那契數列,漢諾塔)演算法
漢諾塔問題

手把手教你用java實現資料結構(五)-----查詢(二分法),遞迴(斐波那契數列,漢諾塔)演算法
完整程式碼:

package com.yueqian.shujujiegou;
/**
 * 資料結構------遞迴演算法----漢諾塔問題
 * @author LinChi
 *
 */
public class DiGui_HanNuoTa {
	public static void main(String[] args) {
		hanNuoTa(3, 'A', 'B', 'C');
	}
	/**
	 * 
	 * @param n     總共的盤子數
	 * @param from  開始移動的柱子
	 * @param in	中間的柱子
	 * @param to 	目標的柱子
	 * 無論多少個盤子,都認為只有兩個,上面的所有盤子,和下面最大的一個盤子
	 */
	public static void hanNuoTa(int n,char from,char in,char to) {
		if(n==1) {
			System.out.println("第1個盤子從"+from+"移動到"+to);
		}else {
			//移動上面所有的盤子到中間位置
			hanNuoTa(n-1,from,to,in);
			//移動下面最大的盤子
			System.out.println("第"+n+"個盤子從"+from+"移動到"+to);
			//將上面所有的盤子從中間位置移動到目標位置
			hanNuoTa(n-1,in,from,to);
		}
	}
}
複製程式碼

敲黑板

面對以上的幾種資料結構演算法問題,小夥伴們考慮下這些演算法實現的思想,將複雜問題簡單化,尋找規律,拓寬思維,方能解出思路。


推薦自己的github地址:github.com/Lmobject

小可愛們,java實現查詢演算法,遞迴演算法到此就介紹完了,對二叉樹感興趣的可以加關注哦!!!,後期持續更新中。。。。

相關文章