码迷,mamicode.com
首页 > 编程语言 > 详细

七大排序算法

时间:2019-11-02 00:22:49      阅读:86      评论:0      收藏:0      [点我收藏+]

标签:indexof   方法递归   select   查找   ret   树形选择排序   排序   while   直接选择排序   

排序

内部排序

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

直接插入排序

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

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  

七大排序算法

标签:indexof   方法递归   select   查找   ret   树形选择排序   排序   while   直接选择排序   

原文地址:https://www.cnblogs.com/watertreestar/p/11780213.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!