• 七大排序算法


    排序

    内部排序

    插入排序
    • 直接插入排序
    • 希尔排序
    选择排序
    • 简单选择排序
    • 堆排序
    交换排序
    • 冒泡排序
    • 快速排序

    直接插入排序

    给定一组序列,假定第一个记录自成一个有序序列,其余记录为无序序列。接着从第二个记录开始,按照记录的大小依此将当前处理的记录插入到其之前的有序序列中,直到最后一个记录插入到有序序列中为止

    public  static void insertSort(int arr[]){
        // 1. 假设第一个序列的第一个元素是有序的
        // 38,73,27,79,19,76
        if(arr == null || arr.length ==0){
            return ;
        }
        int j = 0;
        // 2. 设置一个下标,从1开始(从第二个元素开始)
        for(int i = 1;i<arr.length;i++){
            // 当前元素和前一个比较
            int temp = arr[i];
            j = i;
            if(temp < arr[j=1]){
                // 前一个比当前的大,则将当前元素放到合适的位置
                // 此处要找出当前元素合适的位置,同时把前面的元素向后移动
                do{
                    arr[j] = arr[j-1];
                    j--;
                }while(arr[j]>temp && j>=1);
    
                arr[j] = temp;
            }
        }
    
    }
    
    排序前:
    38  65  97  76  13  27  49  
    排序后:
    13  27  38  49  65  76  97  
    

    希尔排序(最小增量排序)

    算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量减到1时,进行直接插入排序后,排序完成

    public static void shellSort(int arr[]){
        int length = arr.length;
        // 初始化增量h = length/2,每循环一次增量h/2
        for(int h = length/2;h>0;h=h/2){
            // 对相差当前增量的元素排序
            for(int i = 0;i<length-h;i++){
                int temp ;
                if(arr[i+h]<arr[i]){
                    temp = arr[i+h];
                    arr[i+h] = arr[i];
                    arr[i] = temp;
                }
            }
        }
    }
    
    排序前:
    38  65  97  76  13  27  49  
    shell排序后:
    13  27  38  49  65  76  97  
    

    简单选择排序

    在要排序的一组数中,选出最小的一个数与第一个位置的数交换;

    然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止

    public static void selectSort(int arr[]){
    		int minLocation = 0;
    		// 在序列中挑选出最小的一个数和第一个交换
    		for(int i = 0;i<arr.length;i++){
    			int temp = arr[i];  // 最小的数
    			// 遍历查找出最下的数
    			for(int j = i+1;j<arr.length;j++){
    				if(temp > arr[j]){
    					temp = arr[j];  // temp 为最小的数
    					minLocation = j;
    				}
    			}
    			// 到此,找出了本次循环最小的数和最小数的位置
    			// 交换
    			if(minLocation != i){
    				arr[minLocation] = arr[i];
    				arr[i] = temp;
    			}
    			
    		}
    }
    
    排序前:
    38  65  97  76  13  27  49  
    选择排序后:
    13  27  38  49  65  76  97  
    

    堆排序

    堆排序是一种树形选择排序,是对直接选择排序的有效改进。

    冒泡排序

    在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。

    public static void bubbleSort(int[] arr){
        int i;
        int j;
        int temp  = 0;
    
        for ( i = 0; i < arr.length; i++) {
            // 内部循环从序列末尾开始
            for(j = arr.length-1;j>i;j--){
                if(arr[j-1] > arr[j]){
                    // 交换
                    temp = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = temp;
                }
    
    
            }
        }
    }
    
    排序前:
    38  65  97  76  13  27  49  21  5  8  6  4  8  3  9  
    冒泡排序后:
    3  4  5  6  8  8  9  13  21  27  38  49  65  76  97  
    

    快速排序

    快速排序是一种非常高效的排算法,它采用了分而治之的思想,把大的拆成小的,小的再拆分为更小的

    基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。

    public static void quickSort(int []arr){
        sort(arr, 0, arr.length-1);
    
    }
    
    private static void sort(int arr[],int low,int high){
        // 选择基准元素,扫描一遍
        if(low>=high)  return;
        int i = low;
        int j = high;
        int key = arr[low];   // 选择基准元素
        while(j>i){
            /*if(arr[i]>arr[j]){
    				//
    			}*/   
            // 可能会出现连续的比关键字大的,就需要继续找,所以使用循环
            // 从后向前比较
            while(j>i && key <= arr[j]){ // 如果没有比关键字小的,则比较下一个,直到有比关键字小的交换位置
                j--;
            }
            // 找出比关键字小的位置,交换两个位置的元素
            if(arr[j]<=key){
                int temp = arr[j];
                arr[j] = arr[i];
                arr[i] = temp;
            }
    
            // 从前向后比较
            while(j>i && key >= arr[i]){ // 如果没有比关键字小的,则比较下一个,直到有比关键字小的交换位置
                i++;
            }
            if(arr[i]>=key){
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
        //此时第一次循环比较结束,
        //关键值的位置已经确定了。左边的值都比关键值小,右边的值都比关键值大,
        //但是两边的顺序还有可能是不一样的,进行下面的递归调用
        // 递归
        sort(arr, low, i-1);
        sort(arr,j+1,high);
    }
    
    排序前:
    38  65  97  76  13  27  49  21  5  8  6  4  8  3  9  58  66  75  22  93  91  10  
    冒泡排序后:
    3  4  5  6  8  8  9  10  13  21  22  27  38  49  58  65  66  75  76  91  93  97 
    

    并归排序

    并归排序的思想:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。

    使用技术: 递归分治

    先拆分再组合

    并归时排序,采用双指针分别指向左半边和右半边,左半边的和有半边的比较大小,小的一边存入新的数组并自增

    public static void mergeSort(int []arr,int low,int high){
        if(low < high){
            int mid = (low+high)/2;
            mergeSort(arr, low, mid);  //  左边
            mergeSort(arr, mid+1, high); // 右边
            merge(arr, low, mid, high);
        }
    }
    private static void merge(int arr[],int low,int mid,int high){
        int temp[] = new int [high-low+1];
        int left = low;
        int right = mid + 1;
        int indexOfTemp = 0;   // temp 数组中的索引
    
        // 此时左边数组的数为有序的
        while(left<=mid && right<=high){
            // 比较左右两个,找出小的放到temp中
            if(arr[left] < arr[right]){
                temp[indexOfTemp++] = arr[left++];
            }else{
                temp[indexOfTemp++] = arr[right++];
            }
        }
    
        while(left <= mid){
            temp[indexOfTemp++] = arr[left++];
        }
        while(right <= high){
            temp[indexOfTemp++] = arr[right++];
        }
        // temp -> arr
        for(int i = 0;i<temp.length;i++){
            arr[low + i] = temp[i]; 
        }
    }
    
    排序前:
    58  66  75  22  93  91  10  16  52  18  90  77  44  29  
    并归排序后:
    10  16  18  22  29  44  52  58  66  75  77  90  91  93  
    
  • 相关阅读:
    线程
    简单排序
    SSM的整合
    SpringMVC中的拦截器、异常处理器
    SpringMVC的文件上传
    SpringMVC的数据响应和结果视图
    springMVC的常用注解
    SpringMVC入门
    Spring中声明式事务控制
    JdbcTemplate在spring中的使用
  • 原文地址:https://www.cnblogs.com/watertreestar/p/11780213.html
Copyright © 2020-2023  润新知