圖解
二分查詢
概念
- 二分查詢也稱折半查詢(Binary Search),它是一種效率較高的查詢方法。但是,折半查詢要求線性表必須採用順序儲存結構,而且表中元素按關鍵字有序排列。
優點
- 查詢速度快
缺點
- 待查表為有序表
演算法思路
- 首先,假設表中元素是按升序排列,將表中間位置記錄的關鍵字與查詢關鍵字比較,如果兩者相等,則查詢成功;否則利用中間位置記錄將表分成前、後兩個子表,如果中間位置記錄的關鍵字大於查詢關鍵字,則進一步查詢前一子表,否則進一步查詢後一子表。重複以上過程,直到找到滿足條件的記錄,使查詢成功,或直到子表不存在為止,此時查詢不成功。
動畫演示
需求: 找到有序表裡面的 “ 1 ”
程式碼
/**
* 二分查詢
*/
public static int binarySearch(int[] array,int fromIndex,int toIndex,int key){
int low=fromIndex;
int high=toIndex-1;
while(low<=high){
int mid=(low+high)/2;//取中間
int midVal=array[mid];
if(key>midVal){//去右邊找
low=mid+1;
}else if(key<midVal){//去左邊找
high=mid-1;
}else{
return mid;
}
}
return -(low+1);//low+1表示找不到時停在了第low+1個元素的位置
}
複製程式碼
快速排序
概念
-
快速排序(Quicksort)是對氣泡排序的一種改進。
快速排序由C. A. R. Hoare在1962年提出。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
動畫演示
程式碼例項
//快速排序 31 21 59 68 12 40
// x=31
public static void quickSort(int[] array,int begin,int end){
if(end-begin<=0) return;
int x=array[begin];
int low=begin;//0
int high=end;//5
//由於會從兩頭取資料,需要一個方向
boolean direction=true;
L1:
while(low<high){
if(direction){//從右往左找
for(int i=high;i>low;i--){
if(array[i]<=x){
array[low++]=array[i];
high=i;
direction=!direction;
continue L1;
}
}
high=low;//如果上面的if從未進入,讓兩個指標重合
}else{
for(int i=low;i<high;i++){
if(array[i]>=x){
array[high--]=array[i];
low=i;
direction=!direction;
continue L1;
}
}
low=high;
}
}
//把最後找到的值 放入中間位置
array[low]=x;
//開始完成左右兩邊的操作
quickSort(array,begin,low-1);
quickSort(array,low+1,end);
}
複製程式碼
歸併排序
概念
- 歸併排序(MERGE-SORT)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併。
演算法思路
-
歸併操作(merge),也叫歸併演算法,指的是將兩個順序序列合併成一個順序序列的方法。
如 設有數列{6,202,100,301,38,8,1}
初始狀態:6,202,100,301,38,8,1
第一次歸併後:{6,202},{100,301},{8,38},{1},比較次數:3;
第二次歸併後:{6,100,202,301},{1,8,38},比較次數:4;
第三次歸併後:{1,6,8,38,100,202,301},比較次數:4;
總的比較次數為:3+4+4=11;
逆序數為14;
動畫演示
上程式碼
@Test
public void test(){
int[] array=new int[]{2,1,6,4,3,9,8,10,7,5};
// merge(array,0,4,7);
mergeSort(array,0,array.length-1);
for (int i : array) {
System.out.print(i+" ");
}
}
public static void mergeSort(int array[],int left,int right){
if(left==right){
return;
}else{
int mid=(left+right)/2;
mergeSort(array,left,mid);
mergeSort(array,mid+1,right);
merge(array,left,mid+1,right);
}
}
// 0 4 7
// 1 2 5 9 === 3 4 10 11
public static void merge(int[] array,int left,int mid,int right){
int leftSize=mid-left;
int rightSize=right-mid+1;
//生成陣列
int[] leftArray=new int[leftSize];
int[] rightArray=new int[rightSize];
//填充資料
for(int i=left;i<mid;i++){
leftArray[i-left]=array[i];
}
for(int i=mid;i<=right;i++){
rightArray[i-mid]=array[i];
}
//合併
int i=0;
int j=0;
int k=left;
while(i<leftSize && j<rightSize){
if(leftArray[i]<rightArray[j]){
array[k]=leftArray[i];
k++;i++;
}else{
array[k]=rightArray[j];
k++;j++;
}
}
while(i<leftSize){
array[k]=leftArray[i];
k++;i++;
}
while(j<rightSize){
array[k]=rightArray[j];
k++;j++;2
}
}
複製程式碼