1. 程式人生 > >關於資料結構演算法中的比較排序(一)(附Java程式碼實現)

關於資料結構演算法中的比較排序(一)(附Java程式碼實現)

     現在已經是10月份,秋招正在進行,不知道是不是有的人會和我一樣正在瘋狂的複習起資料結構,在這裡我將就常見的幾種比較排序做一些簡單的解析,同時附上具體的程式碼實現。

1.氣泡排序

氣泡排序通常是我們最先接觸道的比較排序的一種,具體排序步驟如下:

1.比較相鄰的元素,如果前一個比後一個大(小),就把它們兩個調換位置;

2.對每一對相鄰元素做同樣的工作,從開始從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大(小)的數,為已排序元素;

3.針對所有未排序元素重複上述步驟,直至沒有任何一對數字需要比較為止,得到即為已排序列;

    public void bubbleSort(int[] array) {
        int l = array.length;
        for (int j = 0; j < l; j++) {
            for (int i = 0; i < l - j; i++) {
                // 依次比較相鄰的兩個元素,使較大的那個向後移
                if (array[i] > array[i + 1]){
                    //此方法用來表示交換array陣列中第i個和第i+1個元素的值
                    swapData(array, i, i + 1);
                }
            }
        }
    }

2.選擇排序

一種非常好理解的演算法,故名思意,就是要不斷從未排序元素中選擇出最大(小)元素,具體排序步驟如下:

1.在序列中尋找最大(小)元素,放到序列的起始位置作為已排序序列;

2.從剩餘未排序元素中繼續尋找最大(小)元素,放到已排序序列的末尾;

3.重複步驟直至所有元素排序完畢。

	public void selectionSort(int[] array){
		int l = array.length;
		for (int i = 0; i < l; i++){
	        int min = i;
	        for (int j = i + 1; j < l; j++){
	            if (array[j] < array[min]){
	                min = j;
	            }
	        }
	     // 放到已排序序列的末尾,該操作很有可能把穩定性打亂,所以選擇排序是不穩定的排序演算法
	        if (min != i){
	        	swaphData(array, min, i);    
	        }
	    }
	}

3.插入排序

類比抽撲克牌,牌堆為未排序序列,手牌中為已排序列,抽一張牌,與手中的牌逐一進行比較,比較後插入對應位置,接著再抽一張牌,直至牌堆無牌可抽,排序即完成,具體步驟如下:

1.從第一個元素開始,該元素可以認為已經被排序; 2.取出下一個元素,在已經排序的元素序列中從後向前掃描; 3.如果該元素(已排序)大於新元素,將該元素移到下一位置; 4.重複步驟3,直到找到已排序的元素小於或者等於新元素的位置; 5.將新元素插入到該位置後; 6.重複步驟2~5。

	//普通的插入排序
    public void insertionSort(int[] array) {
		int l = array.length;
		for (int i = 1; i < l; i++){
			//先獲取一個數據
	        int get = array[i];                
	        int j = i - 1;
	        //將獲取的資料右向左進行比較
	        while (j >= 0 && array[j] > get){
	        	// 如果該手牌比抓到的牌大,就將其右移
	        	array[j + 1] = array[j];            
	            j--;
	        }
	        array[j + 1] = get; // 直到該手牌比抓到的牌小(或二者相等),將抓到的牌插入到該手牌右邊(相等元素的相對次序未變,所以插入排序是穩定的)
	    }
	}
    //使用二分法對插入排序進行優化	
    public void insertionSortDichotomy(int[] array){
		int l = array.length;
		for (int i = 1; i < l; i++){
			// 右手抓到一張撲克牌
	        int get = array[i];                    
	        // 拿在左手上的牌總是排序好的,所以可以用二分法
	        int left = 0;                   
	        // 手牌左右邊界進行初始化
	        int right = i - 1;                
	        while (left <= right){
	            int mid = (left + right) / 2;
	            if (array[mid] > get)
	                right = mid - 1;
	            else
	                left = mid + 1;
	        }
	     // 將欲插入新牌位置右邊的牌整體向右移動一個單位
	        for (int j = i - 1; j >= left; j--){
	        	array[j + 1] = array[j];
	        }
	     // 將抓到的牌插入手牌
	        array[left] = get;                    
	    }
	}