排序算法——冒泡,选择,插入,希尔,归并,快排

263 阅读4分钟

各种时间算法的时间复杂度

冒泡排序

// 将大/小值放到前面
void bubbleSort(int pInt[], int len) {
   for (int i = 0; i < len - 1; ++i) {
       for (int j = i + 1; j < len; ++j) {
           if (pInt[i] > pInt[j]) {
               int temp = pInt[i];
               pInt[i] = pInt[j];
               pInt[j] = temp;
           }
       }
   }
}
// 将大/小的值放到后面
//void bubbleSort1(int arr[], int len) {
//    for (int i = 0; i < len - 1; ++i) {       // n
//        for (int j = 0; j < len - i - 1; ++j) {   //
//            if (arr[j] > arr[j + 1]) {
//                int temp = arr[j];
//                arr[j] = arr[j + 1];
//                arr[j + 1] = temp;
//            }
//        }
//    }
//}

冒泡时间复杂度求解过程

选择排序


void select_sort(int arr[], int len) {
    for (int i = 0; i < len; ++i) {
        int min = i;
        for (int j = i + 1; j < len; ++j) {
            if (arr[min] > arr[j]) {
                min = j;
            }
        }
        if (min != i) {
            int temp = arr[i];
            arr[i] = arr[min];
            arr[min] = temp;
        }
    }
}

直接插入排序

在基本有序的情况下,最具有优势。

插入排序思想

 void insert_sort(int array[]) {
        int len = array.length;
        int i, j;
        for (i = 1; i < len; i++) {
            int temp = array[i];
            // 注意点    j>0  一定要在前面,否在数组越界
            for (j = i; j > 0 && array[j - 1] > temp; j--) {
            // 元素往后挪,为temp找到对的位置
                array[j] = array[j - 1];
            }
            array[j] = temp;
        }
        System.out.println(Arrays.toString(array));
    }

希尔排序

在直接插入排序的基础上增加步长。步长的作用的作用是将数组整理成基本有序状态。 最坏的情况下等价于直接插入排序。

void shell_sort(int arr[]) {  //
        int len = arr.length;   // len:8
        int step = len / 2;
        int i, j, k;
        while (step > 0) { // 进行 分组   ,
            for (i = 0; i < step; i++) {   //  i 是开始位置
                for (j = i + step; j < len; j += step) {// j 是结束位置
                    int temp = arr[j];//保存结束位置,前面的元素会往后移位for (k = j; k > i && arr[k - step] > temp; k -= step) {  // k等于结束位置,大于i(开始位置)时,减减
                        arr[k] = arr[k - step];
                    }
                    arr[k] = temp;
                }
            }
            step /= 2;
        }
    }

希尔排序思想

归并排序

归并排序思想

拆分过程

进行归并
1,将原数组中的数据拷贝到temp数组中
2,定义3个变量
i 指向缓存数据的最左边
j 指向缓存数组的mid+1
k 指向原数组最左边的位置,
3,对缓存数组中的i和j进行比较,小的放到原数组中(根据k索引)
4,边界处理 ++处理
左边(i>mid)时,拷贝(移位)右边(j)
右边(j>r)时,拷贝(移位)左边i

      
public class MergeSort {
    public static void main(String[] args) {
        int array[] = {3, 1, 2, 6, 4, 3, 4, 6}; 
        MergeSort javaMain = new MergeSort(); 
        javaMain.margeSort(array);
     }

    private void margeSort(int[] array) {
        int len = array.length - 1;
        margeSort_(array, 0, len);
    }
//递归进行 拆分
    private void margeSort_(int[] array, int l, int r) {
        if (l >= r) {
            return;
        }
        int mid = (l + r) >> 1;
        margeSort_(array, l, mid);
        margeSort_(array, mid + 1, r);

        if (array[mid] > array[mid + 1]) {
            marge(array, l, mid, r);
        }
    }

    private void marge(int[] array, int l, int mid, int r) {
        int temp[] = new int[r - l + 1];
        for (int i = l; i <= r; i++) {
            temp[i - l] = array[i];
        }
        // 从原数组的最左边开始进行索引.
        int k = l;
        // 分别指向拷贝数组的两个位置,进行比较,谁小,将谁放到原数组的对应位置,并且自加
        int i = l;
        int j = mid + 1;
        for (; k <= r; k++) {
            if (i > mid) {
                array[k] = temp[j - l];
                j++;
            } else if (j > r) {
                array[k] = temp[i - l];
                i++;
            } else if (array[i] > array[j]) {
                array[k] = temp[j - l];
                j++;
            } else {
                array[k] = temp[i - l];
                i++;
            }
        }
    }
}

快速排序

取一个数据,将小于这个数据的放左边,大于这个数据的放在右边,一轮下来后,这个数据所在的位置就是已经排好序了。

public class QuickSort {
    public static void main(String[] args) {
        int arr[] = {3, 1, 2, 6, 4, 3, 4, 6};
        QuickSort quickSort = new QuickSort();
        quickSort.quickSort(arr, arr.length);
        System.out.println(Arrays.toString(arr));
    }
    private void quickSort(int[] arr, int length) {
        quickSort_(arr, 0, length - 1);
    }
    private void quickSort_(int[] arr, int l, int r) {
        if (l >= r) {
            return;
        }
        int p = position(arr, l, r);
        quickSort_(arr, l, p);
        quickSort_(arr, p + 1, r);
    }
// 以左边的的数组为标准,将大于的放在右边,小于的放在左边。返回所在位置的下标
    private int position(int arr[], int l, int r) {
        int v = arr[l];  // 记录 最左边的标准值v
        int p = l;       // 返回的p值,默认在最左边
        for (int i = l; i <= r; i++) { // i不停的寻找 比v小的值,找到不,让p进行交换
            if (arr[i] < v) {// 第一次,是等于,第二次如果小于v,则会和自己进行交换
                p++;
                int temp = arr[i];
                arr[i] = arr[p];
                arr[p] = temp;
               
            }
        }
        // p所在的最终的位置是v应该在的位置
        int temp = arr[p];
        arr[p] = arr[l];
        arr[l] = temp;
        return p;
    }
} 

demo github.com/eerry/werwe…