//排序和查找是數據結構與算法設計的重要內容
/*
排序主要包括
1.插入排序:又包括直接插入排序、二分法插入排序、表插入排序、Shell排序
2.選擇排序:包括直接選擇排序、堆排序
3.交換排序:冒泡排序、快速排序
4.分配排序:主要有基數排序
5.歸並排序:主要有內排序、外排序
注:以下程序均在本人電腦上通過完整的數據測試
*/
/////////////////////////////////////////////////////////
/////////////1.冒泡排序//////////////////////////////////
/////////////////////////////////////////////////////////
/*算法分析:
依次比較相鄰的兩個數,將大數放在前面,小數放在后面。
即首先比較第1個和第2個數,將大數放前,小數放后。然
后比較第2個數和第3個數,將大數放前,小數放后,如此
繼續,直至比較最后兩個數,將大數放前,小數放后,此
時第一趟結束,在最后的數必是所有數中的最小數。重復
以上過程,仍從第一對數開始比較(因為可能由於第2個數
和第3個數的交換,使得第1個數不再大於第2個數),將大
數放前,小數放后,一直比較到最小數前的一對相鄰數,
將大數放前,小數放后,第二趟結束,在倒數第二個數中得
到一個新的最小數。如此下去,直至最終完成排序。
*/
public class MaoPao {
public void BubbleSort(int a[]) {
int temp = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a.length - i - 1; j++) {
if (a[j] > a[j + 1]) {
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
}
for (int item : a) {
System.out.println(item);
}
}
public static void main(String[] args) {
MaoPao mp = new MaoPao();
int[] a = { 49, 38, 65, 97, 76, 13, 27 };
mp.BubbleSort(a);
}
}
/////////////////////////////////////////////////////////
/////////////2.快速排序//////////////////////////////////
/////////////////////////////////////////////////////////
/**算法分析:
*
* 快速排序對冒泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的
* 兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分
* 數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
*
* 設要排序的數組是A[0]……A[N-1],首先任意選取一個數據(通常選用第一個數據)作為關鍵
* 數據,然后將所有比它小的數都放到它前面,所有比它大的數都放到它后面,這個過程稱為一
* 躺快速排序。一躺快速排序的算法是:
1)設置兩個變量I、J,排序開始的時候:I=0,J=N-1;
2)以第一個數組元素作為關鍵數據,賦值給X,即 X=A[0];
3)從J開始向前搜索,即由后開始向前搜索(J=J-1),找到第一個小於X的值,讓該值與X交換;
4)從I開始向后搜索,即由前開始向后搜索(I=I+1),找到第一個大於X的值,讓該值與X交換;
5)重復第3、4步,直到 I=J;
例如:待排序的數組A的值分別是:(初始關鍵數據:X=49)
A[0] 、 A[1]、 A[2]、 A[3]、 A[4]、 A[5]、 A[6]:
49 38 65 97 76 13 27
進行第一次交換后: 27 38 65 97 76 13 49
( 按照算法的第三步從后面開始找)
進行第二次交換后: 27 38 49 97 76 13 65
( 按照算法的第四步從前面開始找>X的值,65>49,兩者交換,此時:I=3 )
進行第三次交換后: 27 38 13 97 76 49 65
( 按照算法的第五步將又一次執行算法的第三步從后開始找
進行第四次交換后: 27 38 13 49 76 97 65
( 按照算法的第四步從前面開始找大於X的值,97>49,兩者交換,此時:J=4 )
此時再執行第三步的時候就發現I=J,從而結束一躺快速排序,那么經過一趟快速排序之后的結果是:
27 38 13 49 76 97 65,即所以大於49的數全部在49的后面,所以小於49的數全部在49的前面。
快速排序就是遞歸調用此過程——在以49為中點分割這個數據序列,分別對前面一部分和后面一部分
進行類似的快速排序,從而完成全部數據序列的快速排序,最后把此數據序列變成一個有序的序列,
根據這種思想對於上述數組A的快速排序的全過程如圖6所示:
初始狀態 {49,38,65,97,76,13,27}
進行一次快速排序之后划分為 {27 38 13} 49 {76 97 65}
分別對前后兩部分進行快速排序 {27 38 13} 經第三步和第四步交換后變成 {13 27 38} 完成排序。
{76 97 65} 經第三步和第四步交換后變成 {65 76 97} 完成排序。
*
*/
public class QuickSort {
public int partition(int[] a, int i, int j) {//分割排序
int key = a[i];
while(i < j) {
while(i < j && a[j] >= key) //找出第一個比key小,並記下j值
j--;
a[i] = a[j];//將a[j]移至a[i]處
while(i < j && a[i] <= key)//找出第一個比key大,並記下i值
i++;
a[j] = a[i];//將a[i]移至a[j]處
}
a[i] = key;//此時完成一趟排序
return i;//此時i=j,記下i的值
}
public void sort(int[] a, int i, int j) {//遞歸調用分割
if(i < j) {
int n = partition(a,i,j);//排一次序列,並獲取關鍵值的位置
sort(a,i,n-1);//左遞歸
sort(a,n+1,j);//右遞歸
}
}
public static void main(String[] args) {
int[] a = {49,38,65,97,76,13,27};
new QuickSort().sort(a, 0, 6);
for(int item : a) {
System.out.println(item);
}
}
}
/////////////////////////////////////////////////////////
/////////////3.折半(二分)法查找////////////////////////
/////////////////////////////////////////////////////////
/**算法分析
*
* 將數列按有序化(遞增或遞減)排列,查找過程中采用跳躍式方式查找,
* 即先以有序數列的中點位置為比較對象,如果要找的元素值小於該中
* 點元素,則將待查序列縮小為左半部分,否則為右半部分。通過一次
* 比較,將查找區間縮小一半。
折半查找是一種高效的查找方法。它可以明顯減少比較次數,提高查
找效率。但是,折半查找的先決條件是查找表中的數據元素必須有序。
* 雖然二分(折半)查找的效率高,但是要將表按關鍵字排序。而排序本身是一
* 種很費時的運算。即使采用高效率的排序方法也要花費 O(n lg n)
* 的時間。
二分查找只適用順序存儲結構。為保持表的有序性,在順序結構里插
入和刪除都必須移動大量的結點。因此,二分查找特別適用於那種一經建
立就很少改動、而又經常需要查找的線性表。
對那些查找少而又經常需要改動的線性表,可采用鏈表作存儲結構,
進行順序查找。鏈表上無法實現二分查找
*/
import java.util.Arrays;
public class Search{
public void HalfSearch(int[] a, int b) {
Arrays.sort(a);//系統排序
int low = 0;
int high = a.length - 1;
int mid = (low + high) / 2;
while ((mid != low) && (mid != high)) {
if (b <= a[mid]) {
high = mid;
mid = (low + high) / 2;
}
else {
low = mid;
mid = (low + high) / 2;
}
}
if ((b == a[low]) || (b == a[high])) {
System.out.println(b + "在數組a中");
}
else {
System.out.println(b + "不在數組a中");
}
}
public static void main(String[] args){
Search s=new Search();
int[] a={11,41,17,18,14,16,20,45};
s.HalfSearch(a,20);
}
}