1. 程式人生 > >二分查詢、快速排序、遞迴呼叫的分析

二分查詢、快速排序、遞迴呼叫的分析

常見的基礎演算法,相信大家見過很多。接下來我來分析下二分查詢、和快速排序演算法。

二分查詢:

前提是在已經排好序的陣列中,通過查詢的元素與中間元素索引值對應的元素進行比較,若大於中間索引值的元素,則向陣列右半部分查詢元素。依次類推,直到找到為止;找不到就返回一個負數;

二分查詢的時間複雜度為O(log n)

下面是二分查詢的程式碼:

/**
 * 二分查詢法(折半查詢):前提是在已經排好序的陣列中,通過待查詢的元素中與中間元素索引值對應的元素進行比較,若大於中間索引值對應的元素,去右半部分查詢;
 * 否則去左半部分查詢。一次類推,直到找到為止;找不到就返回一個負數;
 *
 *
 */
public class Erfenchazhao {
public static void main(String []args){
	int [] num = {10,20,40,80,100,150,200,280,420,500};//一個數組
	Erfenchazhao e = new Erfenchazhao();
	int index = e.binarysearch(num, 100);//將查詢到的元素索引值賦值給index
	System.out.println(index);
}
public int binarysearch(int []num,int pointnumber){ //pointnumber表示要尋找的數字
	int start = 0;   //開始位置的下標
	int last= num.length-1;   //結束位置的下標
	while(start<=last){
		int middle = (start+last)/2; //中間索引值位置的下標
		if(num[middle]<pointnumber){ //若查詢到的元素在右半部分
			start = middle+1;
		}
		else if(num[middle]>pointnumber){ //若查詢到的元素在右半部分
			last=middle-1;
		}
		else{
			return middle; //找到了就返回元素的索引值
		}
	}
	return -1; 找不到就返回-1
}
}

 快速排序:

快速排序的時間複雜度為:n(logn),但是最糟糕的情況和冒泡選擇一樣時間複雜度為(n*n)

快速排序運用了分治法,先比較大小再分割槽:

1.先從陣列中取出一個數作為基準數。

2.分割槽:將比這個數大的或等於的數放在它的右邊,小於它的數全部放到它的左邊。

3.在對左右取件重複第二步,直到各區間只有一個數;

實現思路:

挖坑填數:

1.把基準數挖出形成第一個坑

2.由後向前查詢比它小的數,找到後挖出此數填到前一個坑中。

3.由前向後找比它大或等於的數,找到後也挖出此數填到前一個坑中。

4.重複執行第2步,第3步;

下面是程式碼:

public class Quickpaixu {
//以索引值進行分割槽
public void quicksort(int []num,int start,int last){
	if(start<last){
		int index=getindex(num,start,last);
		quicksort(num,start,index-1);
		quicksort(num,index+1,last);
	}
}
//獲取基準數的索引值
public int getindex(int []num,int start,int last){
	int i=start;//第一個元素的下標
	int j=last;//最後一個元素的下標
	int temp=num[i];//第一個坑的資料
	while(i<j){
		//先從右往左對比,找到小於temp的數
		while(i<j&&num[j]>=temp){
			j--;
		}
		if(i<j){
			//把找到的元素放入對個坑位
			num[i]=num[j];
			i++;
		}
		//從左往右對比,找到大於等於temp的數
		while(i<j&&num[i]<temp){
			i++;
		}
		if(i<j){
			num[j]=num[i];
			j--;
		}
	}
	num[i]=temp;
	return i;
}
public static void main(String []args){
int [] num={12,1,9,15,60,7,99,7,44,60};
Quickpaixu q = new Quickpaixu();
q.quicksort(num, 0, num.length-1);
for(int i=0;i<num.length;i++){
	System.out.println(num[i]);
}
}
}

遞迴呼叫:

遞迴是指在函式的定義中使用函式自身的方法。

在編碼遞迴函式的時候,必須告訴它何時停止遞迴。因此每個遞迴函式分為兩部分:基線條件和遞迴條件;

基線條件指的是函式不在呼叫自己,從而避免無限迴圈下去。

遞迴條件指能夠不停呼叫自己的方法。

下面是一個Fabonacci數列的問題例子,Fabonacci數列的描述是這樣的,當n<=2時,f(1)=1,f(2)=1。  當n>=3時,f(n)=f(n-1)+f(n-2);

public class Digui {
public int f(int n){
	if(n==1||n==2){//當n等於1或者2時,跳出遞迴方法。
		return 1;
	}
	else{//當n大於2時不停呼叫遞迴方法,也就是己方法。
		return f(n-1)+f(n-2);
	}
	
}
public static void main(String []args){
	Digui d = new Digui();
	int x=d.f(40);//得到f方法得到f(40)的值。
	System.out.println(x);
}
}

上面是我的一些我對二分查詢、快速排序、遞迴呼叫演算法的簡單的理解,錯誤之處,還請糾正。