【数据结构与算法之美】十大排序思路及代码实现

1.冒泡排序

1.1 实现思路

冒泡排序思想是通过将两个互相相邻的元素进行比较,如果前一个元素大于后一个元素,进行交换位置。否则不交换。外层循环控制层数,内存循环控制个数。每进行一轮都会将最大数字移动到最后,所以经过多次交换就可以实现将数组中的元素进行有序排列了。

note:我们在内存循环中加入一个判断标志 如果当前内存循环没有进行交换数据的操作 说明这个数组的元素已经是有序的 就可以退出循环操作。

1.2 代码实现

public static void bubbleSort(int [] arr){
        for (int i = 0; i < arr.length-1; i++) {
            boolean flag = true;
            for (int j = 0; j < arr.length-1-i; j++) {
                if (arr[j]>arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    flag = false;
                }
            }
            if (flag){
                break;
            }
        }
    }

2.选择排序

2.1 实现思路:

选择排序主要每次选择一个最小的下标值,在内层循环中找到最小值下标,循环n次找到最小值。最后将预先寻找的值与最小下标值进行交换,每次选择一个最小的。多次循环就可以将一个无序的数组转换成一个有序的数组了。

2.2 代码实现

   public static void selectSort2(int[] arr) {
            for (int i = 0; i < arr.length - 1; i++) {
                int minIndex = i;
                for (int j = i + 1; j < arr.length; j++) {
                    if (arr[j] < arr[minIndex]) {
                        minIndex = j;
                    }
                }
                int temp = arr[minIndex];
                arr[minIndex] = arr[i];
                arr[i] = temp;
            }
        }

3.插入排序

3.1 实现思路:

插入排序的思想是 将数组中分为已排好序 和
未拍好序两部分。第一个是已经拍好序的。所以i从1开始每次选择一个元素,插入到已排好序当中。而内层循环所作的就是找到判断当前要插入的元素应该插入的位置。如此反复执行,就可以找到应当插入的位置。

3.2 代码实现

   public static void selectSort2(int [] arr){
            for (int i = 1; i < arr.length; i++) {
                int value = arr[i];
                int j = i-1;
                for (; j >=0 ; j--) {
                    if (arr[j]>value){
                        arr[j+1] = arr[j];//care
                    }else {
                        break;
                    }
                }
                arr[j+1] = value;//care
            }
        }

4.归并排序

4.1 实现思路

归并排序:使用递归思想,将一个无序的数组多次分割成多个小的数组,将小的数组进行元素比较 最小的元素放在前面,反复执行就可以实现数组排序了

4.2 代码实现

   public static void mergeSorts(int[] arr) {
            mergesort(arr, 0, arr.length - 1);
        }
    
        private static void mergesort(int[] arr, int p, int r) {
            if (p >= r) return;
    
            int q = p + (r - p) / 2;
    
            //合并左边
            mergesort(arr, p, q);
            //合并右边
            mergesort(arr, q + 1, r);
    
            merge(arr, p, q, r);
    
        }
    
        private static void merge(int[] arr, int p, int q, int r) {
    
            int i = p;
            int j = q + 1;
            int count = 0;
            //定义一个数组
            int[] tmp = new int[r - p + 1];
            //合并两个数组
            while (i <=q && j<=r) {
                if (arr[i] < arr[j]) {
                    tmp[count++] = arr[i++];
                } else {
                    tmp[count++] = arr[j++];
                }
            }
    
            int start = i;
            int end = q;
            if (j <= r) {//注意边界条件
                start = j;
                end = r;
            }
    
            //转移剩余的元素
            while (start <= end) {
                tmp[count++] = arr[start++];
            }
            //回归arr
            for (int k = 0; k <= (r - p); k++) {
                arr[p+k] = tmp[k];
            }
        }

4.3 简洁版

 private static void mergeSort(int[] array, int left, int right) {
            //条件判断
            if (right <= left) {
                return;
            }
            //中间下标位置
            int mid = (left + right) >> 1;
    
            //左边排序
            mergeSort(array, left, mid);
            //右边排序
            mergeSort(array, mid + 1, right);
            //合并
            merge(array, left, mid, right);
        }
    
        private static void merge(int[] array, int left, int mid, int right) {
            //临时数组
            int[] temp = new int[right - left + 1];
    
            int i = left, j = mid + 1, p = 0;
    
            //比较大小 后存储
            while (i <= mid && j <= right) {
                temp[p++] = array[i] <= array[j] ? array[i++] : array[j++];
            }
            //剩余的存储
            while (i <= mid) {
                temp[p++] = array[i++];
            }
    
            while (j <= right) {
                temp[p++] = array[j++];
            }
    
            //赋值给原来的数组
            for (int k = 0; k < temp.length; k++) {
                array[left + k] = temp[k];  //care
            }
        }

5.快速排序

5.1 实现思路

如果要在排序数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为一个piovt(分区点),我们遍历p到r之间的数据,将小于piovt的放到左边,将大于piovt的放到右边,将piovt放到中间,经过这一步骤之后,数组p到r之间的数据就被分成了三部分,前面是p到q-1之间是小于piovt,中间是piovt
后面的q+1到r之间的是大于piovt。

5.2 代码实现

   private static void quickSort(int[] arr, int start, int end) {
            if(end <= start){
                return;
            }
    
            int piovt = partition(arr,start,end);//获取到piovt下标
            quickSort(arr,start,piovt-1); 
            quickSort(arr,piovt+1,end);
        }
    
        private static int partition(int[] arr, int start, int end) {
            //piovt 标杆位置, counter 小于piovt的元素的个数
            int piovt = end;
            int counter = start;
            for (int i = start; i < end; i++) {
                if (arr[i]<arr[piovt]){  //如果小于Arr[piovt] 移动到piovt前面 否则不动
                    int temp = arr[counter];
                    arr[counter] = arr[i];
                    arr[i] = temp;
                    counter++;
                }
            }
            int temp  = arr[piovt];
            arr[piovt] = arr[counter];
            arr[counter] = temp;
            return counter;
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章