圖解排序算法

       最近以爲本身的編程毫無進展,想修煉下本身的內功,因而就開始複習學習數據結構與算法。其實,編程的人大概都知道一句話「程序等於算法+數據結構」,理解並選用合適的數據結構,還有算法,是編寫出優秀程序的前提。在JAVA JDK中,也能夠窺探出數據結構算法的重要性,好比HashMap中就用到了數組+鏈表提升查找、插入效率。我的也想經過總結編寫文章的方式提升學習效率,因而有這篇文章。爲了逼本身一把,決定之後每週寫一篇博客(不必定都是數據結構與算法)。因爲鄙人水平有限,加之文采極差,還不多寫博客,但願看到文章的各位大佬能提提見解、建議。算法

1、冒泡排序

一、說明編程

冒泡排序,每次冒泡都比較相鄰兩個數的大小,大小關係不對,則交換。以下圖,第一躺冒泡下來,最大的值都會被排到正確的位置,也有可能有其餘數字處於正確位置。因此一趟下來至少有一個最大的處於正確位置(以下圖的9)。數組


第二趟下來,第一趟後剩下的數字中,最大的8又會處於正確位置(以下圖)。
bash


這樣最多冒泡n-1次,就會是一個有序的序列數據結構

二、JAVA代碼實現以下學習

//時間複雜度爲O(n^2) 最好時間複雜度O(n) 平均時間複雜度O(n^2)
public static void sort(int numArray[]) {
	if (numArray == null || numArray.length == 0) {
	   return;
	}
	int arrayLength = numArray.length;
	int tmp;
        //這一趟是否有發生交換,若是沒有發生交換,說明數組已是有序的,不須要再冒泡了。
	boolean flag = false;
	//外層:須要length-1次循環比較,須要作n-1次冒泡
	for(int i= 0; i < arrayLength - 1; i++) {
                flag = false;
    		for(int j=0; j < arrayLength -i-1; j++) {
			//內層:每次循環須要兩兩比較的次數,每次比較後,都會將當前最大的數放到最後位置
			if(numArray[j] > numArray[j+1]) {
				tmp = numArray[j];
				numArray[j] = numArray[j+1];
				numArray[j+1] = tmp;
				flag = true;
			}
		}
		if(!flag) //沒有任何交換,數組已經處於有序
			break;
	}
}
複製代碼


2、選擇排序

一、說明
ui

選擇排序以下圖,每次都找出剩餘中最小的值,將該最小值放到正確位置spa


二、JAVA代碼實現以下
指針

public static void selectSort(int numArray[]) {
	int length = numArray.length;
	int min,pos;
        //每一次循環都會找出剩下中的最小數,放到正確的位置
	for(int i= 0; i < length-1; i++) {
		min = numArray[i];
		pos = i;
                //找出剩餘中的最小數
		for(int j = i+1; j < length; j++) {
			if(numArray[j] < min) {
				min = numArray[j];
				pos = j;
			}
		}
		if(pos != i) {
			numArray[pos] = numArray[i];
			numArray[i] = min;
		}
	}
}複製代碼

3、插入排序

一、說明
code

插入排序同咱們打撲克牌時排序牌同樣,每次抽上一張牌,插入到手上已經有序的牌中。以下例子,咱們從第二個數開始,插入到前面中。以下圖,第二次,6須要插入到前面5,8之間,因此將8後移,以後將6插入。


二、JAVA代碼實現以下

public static void insertSort(int intList[]) {
	int j = 1;
	int i;
	for(; j < intList.length; j++) {
		i = j-1;
		int key = intList[j];
		while(i > -1 && intList[i] > key) {
			intList[i+1] = intList[i];
			i--;
		}
		intList[i+1] = key;
	}
	//時間複製度爲O(n^2) ,最好狀況時間複雜度O(n),平均時間複雜度O(n^2)
}複製代碼

4、快速排序

一、說明

快速排序採用分治的思想,總的思想就是選取一個數字爲基準值,並將全部比它小的元素放到它前面,比它大的元素放到它後面,以後基準值就處於正確位置,分別對基準值先後兩個數組進行排序,最後就會是有序的。快速排序有多種實現方式,如下是經過左右指針實現。


二、JAVA代碼實現以下

public static void quickSort(int numArray[],int _left, int _right) {
	int left = _left;
    int right = _right;
    int temp = 0;
    if(left <= right){   //待排序的元素至少有兩個的狀況
        temp = numArray[left];  //待排序的第一個元素做爲基準元素
        while(left != right){   //從左右兩邊交替掃描,直到left = right

            while(right > left && numArray[right] >= temp)  
                 right --;        //從右往左掃描,找到第一個比基準元素小的元素
            numArray[left] = numArray[right];  //找到這種元素arr[right]後與arr[left]交換

            while(left < right && numArray[left] <= temp)
                 left ++;         //從左往右掃描,找到第一個比基準元素大的元素
            numArray[right] = numArray[left];  //找到這種元素arr[left]後,與arr[right]交換

        }
        numArray[right] = temp;    //基準元素歸位
        quickSort(numArray,_left,left-1);  //對基準元素左邊的元素進行遞歸排序
        quickSort(numArray, right+1,_right);  //對基準元素右邊的進行遞歸排序
    }     
}複製代碼

5、歸併排序

一、說明

歸併排序也是分治思想,先將全部元素分離開,並進行逐步排序,原理以下圖


二、JAVA代碼實現以下

public static int[] sort(int [] a) {
    if (a.length <= 1) {
        return a;
    }
    int num = a.length >> 1;
    int[] left = Arrays.copyOfRange(a, 0, num);
    int[] right = Arrays.copyOfRange(a, num, a.length);
    return mergeTwoArray(sort(left), sort(right));
}

public static int[] mergeTwoArray(int[] a, int[] b) {
    int i = 0, j = 0, k = 0;
    int[] result = new int[a.length + b.length]; // 申請額外空間保存歸併以後數據

    while (i < a.length && j < b.length) { //選取兩個序列中的較小值放入新數組
        if (a[i] <= b[j]) {
            result[k++] = a[i++];
        } else {
            result[k++] = b[j++];
        }
    }

    while (i < a.length) { //序列a中多餘的元素移入新數組
        result[k++] = a[i++];
    }
    while (j < b.length) {//序列b中多餘的元素移入新數組
        result[k++] = b[j++];
    }
    System.out.println(Arrays.toString(result));
    return result;
}
複製代碼
相關文章
相關標籤/搜索