排序演算法,查詢和遞迴的學習
阿新 • • 發佈:2018-11-10
1. 氣泡排序演算法 ##
氣泡排序演算法的中心思想
- 比較相鄰的元素。如果第一個比第二個大,就交換他們兩個。
- 對每一個相鄰元素做同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。
- 針對所有的元素重複以上的步驟,除了最後一個。
4.持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要比較。
/**
1.
2. @param array
3.
4. 氣泡排序演算法
5.
*/
public static void bubbleSort(int array[]) {
for (int i=0;i<array.length-1;i++) {
for(int j=0;j<array.length-1-i;j++) {
if(array[j]>array[j+1]) {
array[j]=array[j]+array[j+1];
array[j+1]=array[j]-array[j+1];
array[j]=array[j]-array[j+1];
}
}
}
for (int i=0;i<array.length;i++) {
if(i!=4) {
System.out.print(array[i]+",");
}else {
System.out.println(array[i]);
}
}
}
仔細研究了下書中的例子,發現自己寫的冒泡演算法很low,並沒有達到這個演算法的最優化,真正的冒泡演算法應該在每輪比較後所需要比較的數字都應該少一個。但是我寫的演算法沒有達到這個要求,經過改良後代碼如下
/**
* 改良版本
* 每輪比較後,最大的數字就會到達陣列的末尾,所以每輪比較過後陣列的總數字應該少一個
*/
public static void bubbleSort2(int [] array) {
//外迴圈確定需要比較多少輪,每輪比較完後,總數少一個,沒有數字需要比較
for (int out = array.length-1; out>0 ; out--) {
for(int in=0;in<out;in++) {
//內迴圈 兩數交換
if(array[in]>array[in+1]) {
array[in]=array[in+1]+array[in];
array[in+1]=array[in]-array[in+1];
array[in]=array[in]-array[in+1];
}
}
}
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
2.簡單選擇排序
簡單選擇排序演算法的中心思想
- 取出陣列中的排在第一位的數字與之後的每一個數字進行比較,若後面的數字比前面的數字小,則兩者交換位置
- 對陣列的數字逐個執行第一步操作,每一輪操作之後,最小的數字會被排到陣列的首部。
- 這樣陣列會從小到大逐個排序
/**
*
* 簡單選擇排序
*/
//兩數交換
public static void exchangeNumber(int array[],int i,int j) {
array[i]=array[i]+array[j];
array[j]=array[i]-array[j];
array[i]=array[i]-array[j];
}
//列印陣列
public static void printArray(int array[]) {
for(int i=0;i<array.length;i++) {
if(i!=4) {
System.out.print(array[i]+",");
}else {
System.out.println(array[i]);
}
}
}
//簡單選擇排序演算法
public static void selectSort(int array[]) {
for(int i=0;i<array.length-1;i++) {
for(int j=i+1;j<array.length;j++) {
if(array[i]>array[j]) {
exchangeNumber(array, i, j);
}
}
}
printArray(array);
}
在需要排序的數字比較少的時候,簡單排序演算法比氣泡排序演算法更快
3.二分查詢
/**
*
* @param array
* 二分法查詢
* 取陣列的中間索引的數(mid)去與要查詢的數字比較
* 若mid比該數字小,則取mid索引作為min繼續取中間值與要查詢的數字進行比較
* 若mid比該數字大,則取mid索引作為max繼續取中間值與該數字比較
* 若mid與該數相等則跳出迴圈,找到要查詢的數字
* min=array[0]
* max=array[array.length-1]
* mid=array[(0+array.length-1)/2]
*/
public static void binarySearch(int[] array,int num) {
int minIndex=0;
int maxIndex=array.length-1;
int midIndex;
if(num<array[0]||num>array[array.length-1]) {
System.out.println("您要查詢的數字不存在");
}
for(int i=0;i<array.length-1;i++) {
midIndex =(minIndex+maxIndex)/2;
if(array[midIndex]<num) {
minIndex=midIndex;
}else if(array[midIndex]>num) {
maxIndex=midIndex;
}else if(array[midIndex]==num) {
System.out.println("第"+(i+1)+"次迴圈"+"找到要查詢的數字"+array[midIndex]);
break;
}else {
System.out.println();
break;
}
}
}
4.遞迴(Recursion)
程式呼叫自身的程式設計技巧稱為遞迴
構成遞迴需要具備的條件
- 子問題需與原始問題為同樣的事,且更為簡單
- 不能無限制的呼叫本身,需有個出口,化簡為非遞迴狀況處理
package com.hwadee.day14;
public class Recursion {
public static void main(String[] args) {
int num=10;
System.out.println(num+"的階乘為"+factorialImpl(num));
for (int i = 0; i <= num; i++) {
System.out.println("第"+(i+1)+"個斐波那契數為:"+fibonacciImpl(i));
}
}
/**
*
*使用遞迴完成階乘
*n!=1*2*3*4...*n
*0!=1 n!=(n-1)!*n
*
*/
public static int factorialImpl(int num) {
return(num==0)?1:num*factorialImpl(num-1);
}
/**
*
* 使用遞迴完成斐波那契數列
* 斐波那契數列:由0和1開始,之後的每個數都是前兩個數的和
*/
public static int fibonacciImpl (int num) {
if(num==0) {
return 0;
}else if(num==1) {
return 1;
}else {
return fibonacciImpl(num-1)+fibonacciImpl(num-2);
}
}
}
//程式執行結果
10的階乘為3628800
第1個斐波那契數為:0
第2個斐波那契數為:1
第3個斐波那契數為:1
第4個斐波那契數為:2
第5個斐波那契數為:3
第6個斐波那契數為:5
第7個斐波那契數為:8
第8個斐波那契數為:13
第9個斐波那契數為:21
第10個斐波那契數為:34
第11個斐波那契數為:55