各種排序演算法思想複雜度及其java程式實現

林加欣發表於2017-11-24

一、氣泡排序(BubbleSort)
1. 基本思想:

設排序表長為n,從後向前或者從前向後兩兩比較相鄰元素的值,如果兩者的相對次序不對(A[i-1] > A[i]),則交換它們,

其結果是將最小的元素交換到待排序序列的第一個位置,我們稱它為一趟冒泡。下一趟冒泡時,前一趟確定的最小元素

不再參與比較,待排序序列減少一個元素,每趟冒泡的結果把序列中最小的元素放到了序列的”最前面”。

 

2.演算法實現

package 氣泡排序;
/**
 * 相鄰資料兩兩比較,大的排上面,小的排下面 第一次可排出最小的值
 * 第二次排出第二小的值
 * 第三次排出第三小的值
 * 以此類推排出順序
 * 
 * 	最優時間複雜度:O(n) (表示遍歷一次發現沒有任何可以交換的元素,排序結束。)
	最壞時間複雜度:O(n2)
	穩定性:穩定
 * @author Administrator
 *
 */
public class BubbleSort {
	//初級版(從左往右比較)
	/**
	 * 	第0次排序==0546897231
		第1次排序==0156897432
		第2次排序==0126897543
		第3次排序==0123897654
		第4次排序==0123498765
		第5次排序==0123459876
		第6次排序==0123456987
		第7次排序==0123456798
		第8次排序==0123456789
		第9次排序==0123456789
		最終排序==0123456789
	 *  最優時間複雜度:O(n) (表示遍歷一次發現沒有任何可以交換的元素,排序結束。)
		最壞時間複雜度:O(n2)
		穩定性:穩定
	 */
	public static void sort1(int[] num){
		int i,j,temp;
		for(i=0;i<num.length;i++){
			//第一次i=0,排出最小的值0
			//第二次i=1,排出第二小的值1
			for(j=i+1;j<num.length;j++){
				if (num[i]>num[j]) {
					temp=num[i];
					num[i]=num[j];
					num[j]=temp;
				}
			}
		}
	}
	//中級版(從右往左比較)
	public static void sort2(int[] num){
		int i,j,temp;
		for(i=0;i<num.length;i++){
			
			for(j=num.length-1;j>i;j--){
				if (num[j-1]>num[j]) {
					temp=num[j-1];
					num[j-1]=num[j];
					num[j]=temp;
				}
			}
			String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
		}
		String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最終排序=="+str2);
		
	}
	//終極版
	public static void sort3(int[] num){
		int i,j,temp;
		boolean flag=true;
		for(i=0;i<num.length&&flag;i++){
			flag=false;
			for(j=num.length-1;j>i;j--){
				//從右往左兩兩相比較,大於說明可以交換數值,小於使用flag=false直接跳過
				if (num[j-1]>num[j]) {
					temp=num[j-1];
					num[j-1]=num[j];
					num[j]=temp;
					flag=true;
				}
			}
		}
	}
	
	
	public static void main(String args[]){
		int[] num={5,2,4,6,8,9,7,1,3,0};
//		sort1(num);
//		sort2(num);
		sort3(num);
	}
	
}

二、選擇排序
1. 基本思想:
從未排好的部分的第一個作為最小(最大)的,然後依次和剩餘的比較,如果有更小(更大)的,記下下標,

以此作為新的最小(最大)值,繼續比較,一趟結束後,可以得到最小值。

例如:初始序列:{49 27 65 97 76 12 38}
  第1趟:12與49交換:12{27 65 97 76 49 38}(選擇第一個數與後面剩下的數兩兩比較,互動位置,排出第一個最小值)
  第2趟:27不動 :12 27{65 97 76 49 38}(第一個數已經排好,選擇第二個數與後面剩下的數兩兩比較,互動位置,排出第二個最小值)
  第3趟:65與38交換:12 27 38{97 76 49 65}(第二個數已經排好,選擇第三個數與後面剩下的數兩兩比較,互動位置,排出第三個最小值)
  第4趟:97與49交換:12 27 38 49{76 97 65}以此類推
  第5趟:76與65交換:12 27 38 49 65{97 76}
  第6趟:97與76交換:12 27 38 49 65 76 97 完成

2. 演算法實現:

package 簡單選擇排序;
/**
 * 選擇一個min做基準和其他的資料相互比較,如果比較的數大則把當前的數的賦值給min
 * 以此類推
 * @author Administrator
 *
 */
public class SelectSort {
	//簡單選擇排序,選擇一個min做基準和其他的資料相互比較
	/**
	 * 最優時間複雜度:O(n2)
		最壞時間複雜度:O(n2)
		穩定性:不穩定(考慮升序每次選擇最大的情況)
	 * @param num
	 */
	public static void sort(int[] num){
		int i,j,min,temp;
		for(i=0;i<num.length;i++){
			min=i;//將當前下標定義為最小值下標
			for(j=i+1;j<num.length;j++){
				if (num[min]>num[j]) {
					min=j;//如果有小於當前最小值的關鍵字,將此關鍵字的下標賦值給min
				}
			}
			if (i!=min) {//若min不等於i,說明min發生改變,即上面相互比較的為true,即有最小值,交換
				temp=num[i];
				num[i]=num[min];
				num[min]=temp;
			}
			String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
		}
		String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最終排序=="+str2);
		
	}
	
	public static void main(String args[]){
		int[] num={5,2,4,6,8,9,7,1,3,0};
		sort(num);

	}
}

三、插入排序(Insertion Sort)
1. 基本思想:

有一個已經有序的資料序列,要求在這個已經排好的資料序列中插入一個數,但要求插入後此資料序列仍然有序,

這個時候就要用到一種新的排序方法——插入排序法,插入排序的基本操作就是將一個資料插入到已經排好序的有序資料中,

從而得到一個新的、個數加一的有序資料,演算法適用於少量資料的排序,時間複雜度為O(n^2)。是穩定的排序方法。

  每次將一個待排序的資料元素,插入到前面已經排好序的數列中的適當位置,使數列依然有序;直到待排序資料元素全部插入完為止。
【示例】:
[初始關鍵字]    [49] 38 65 97 76 13 27 49(選擇49)
    J=2(38)   [38 49] 65 97 76 13 27 49(選擇38插入到49前面)
    J=3(65)   [38 49 65] 97 76 13 27 49(選擇65插入到49前面)
    J=4(97)   [38 49 65 97] 76 13 27 49(選擇97插入到65前面)
    J=5(76)   [38 49 65 76 97] 13 27 49(以此類推)
    J=6(13)   [13 38 49 65 76 97] 27 49
    J=7(27)   [13 27 38 49 65 76 97] 49
    J=8(49)   [13 27 38 49 49 65 76 97] 

2. 演算法實現:

package 直接插入排序;

public class InsertSort {
	/**
	 * 插入排序
	 * 
	 * @paramarr
	 * @return
	 */
	public static void insert(int[] num)  
    {  
        for(int i=1;i<num.length;i++)     //n-1此掃描,依次向前插入n-1個元素  
        {  
            int temp=num[i];       //每趟將num[i]插入到前面的排序子序列中  
            int j;  
            for(j=i-1;j>=0&&temp<num[j];j--)  
            {  
            	num[j+1]=num[j];  //將前面較大的元素向後移動   
            }  
            num[j+1]=temp;      //temp值到達插入位置  
            String str="";
			for (int k : num) {
				str+=k;
			}
			System.out.println("第"+i+"次排序=="+str);
        }
        String str2="";
		for (int k : num) {
			str2+=k;
		}
		System.out.println("最終排序=="+str2);
    }  


	public static void main(String[] args) {
		// TODO 自動生成的方法存根
		int[] num = { 5, 2, 4, 6, 8, 9, 7, 1, 3, 0 };
		insert(num);
	}
}

  

相關文章