经典排序算法-Java

经典排序算法-Java

内排序:排序操作在内存中完成;
外排序:因为数据量较大,所以把数据放在磁盘中,而排序通过磁盘和内存的数据传输才能进行;
稳定:x=y,如果x原本在y前面,排序之后x仍在y前面;
不稳定:x=y,如果x原本在b前面,排序之后x可能会出现在y后面;
时间复杂度: 算法程序执行所耗费的时间成本;
空间复杂度:运行完算法程序所需要的内存大小

基本排序算法:冒泡排序(稳定),插入排序(稳定),选择排序(不稳定)
时间复杂度:O(n^2)
空间复杂度:O(1)

其他排序算法:
归并排序(稳定)——时间复杂度:O(nlogn)、空间复杂度:O(n)

一、冒泡排序

两个for循环,外循环每次排好一个,内循环控制比较的范围(因为已经有i个是排好的),if语句判断是否要交换,变量tmp用来暂存要交换的元素

public class bubbleSort {
    //大的沉到尾部
    public static void bubble_sort(int[] arr){
        int tmp;//暂存要交换的元素
        int len = arr.length;
        for (int i = 0;i < len;i++){//外循环,每次循环确定一个最大元素
            for (int j = 1;j < len-i;j++){//内循环,后面的i个已经排好
                if (arr[j-1] > arr[j]){//如果前一个比后一个大,交换
                    tmp = arr[j];
                    arr[j] = arr[j-1];
                    arr[j-1] = tmp;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {2,5,1,7,4,8,3,1,5,9};
        bubble_sort(arr);
        for (int a = 0;a < arr.length;a++){
            System.out.print(arr[a]+" ");
        }
    }
}
二、选择排序
public class selectionsort {
    public static void main(String[] args) {
        int[] arr = {20,40,30,10,60,50};
        selectionsort ins = new selectionsort();
        ins.select_sort(arr);
    }
    public void select_sort(int[] arr){
        int minpoint;//用来记录最小的元素的下标
        int len = arr.length;//记录长度,可要可不要
        int temp;//交换两个元素时过渡使用

        for (int i = 0;i < len-1;i++){//外循环
            minpoint = i;//初始假设第一个元素是最小的元素,记录下标
            for (int j = i+1;j < len;j++){//比较找出最小元素,前面的i个已经排好,所以从i+1个开始找
                if(arr[minpoint] > arr[j]){//比较
                    minpoint = j;//更新最小记录下标
                }
            }
            if (minpoint!=i){//跟原来的不相等则交换,其实意义不大,就是处理最后一个
                temp = arr[minpoint];
                arr[minpoint] = arr[i];
                arr[i] = temp;
            }
        }
    }
}
三、插入排序
public class insertSort {
    public static void insert_sort(int[] arr){
        int temp;
        for (int i = 1;i < arr.length;i++){//注意要从1开始,因为插入的位置最小也是1前面,不能是0前面
            int p = i-1;//记录要开始比较的位置,即第i个元素的前一个
            temp = arr[i];//记录当前的第i个元素,因为我们把元素往后移动的时候会覆盖
            while(p >= 0 && arr[p] > temp){//当前的小于前面的,前面的那个数往后移动一位
                arr[p+1] = arr[p];
                p--;//往前继续比较
            }
            //直到找到需要插入的位置
            arr[p+1] = temp;
        }
    }

    public static void main(String[] args) {
        int[] arr = {8, 2, 4, 9, 3, 6};
        insert_sort(arr);
        for (int a = 0; a < arr.length; a++) {
            System.out.print(arr[a] + " ");
        }
    }
}
二分插入排序

就是寻找插入位置时使用二分查找

public class insertSort {
    //优化,加入二分查找来确定插入位置
    public static void binarysearch(int[] arr){
        for (int i = 1;i < arr.length;i++){//注意要从1开始,因为插入的位置最小也是1前面,不能是0前面
               if (arr[i] < arr[i-1]){
                   int tmp = arr[i];
                   int low = 0;
                   int high = i-1;
                   while(low <= high){//二分停下条件,“=”是为了解决偶数个元素问题
                       int mid = (low+high)/2;//取中间元素
                       if (arr[mid] > tmp){
                           high = mid-1;
                       }else {
                           low = mid+1;
                       }
                   }
                   for (int j = i-1;j >= low;j++){
                       arr[j+1] = arr[j];
                   }
                   arr[low] = tmp;
               }
        }
    }

    public static void main(String[] args) {
        int[] arr = {8, 2, 4, 9, 3, 6};
        binarysearch(arr);
        for (int a = 0; a < arr.length; a++) {
            System.out.print(arr[a] + " ");
        }
    }
}
四、归并排序
public class merge {//归并排序需要2个方法,一个用于递归拆分成单个元素,一个用于比较排序
    public static void main(String[] args) {
        int[] arr = {3,5,7,1,8,6,3,96,3,33};
        merge_sort(arr,0,arr.length-1);
        for (int a = 0;a < arr.length;a++){
            System.out.print(arr[a]+" ");
        }
    }
    public static void merge_sort(int[] arr, int left, int right){
        int mid = (left+right)/2;
        if(left < right){//每一次都要拆分,而且调用归并排序方法
            merge_sort(arr,left, mid);//左边部分,递归拆分
            merge_sort(arr,mid+1,right);//右边部分,递归拆分
            merge(arr,left,right,mid);//合并每两部分
        }
    }
    public static void merge(int[] arr,int left,int right,int middle){
        int[] temp = new int[right-left+1];
        int i = 0;
        int j = left;//为了能记录住left的值,覆盖原数组时要靠它定位,我们让j去变化
        int k = middle+1;
        while (j <= middle && k <= right){
            if (arr[j] < arr[k]){
                /*temp[i] = arr[j];
                * i++;
                * j++;*/
                temp[i++] = arr[j++];//优化
            }else{
                temp[i++] = arr[k++];
            }
        }
        while(j <= middle){
            temp[i++] = arr[j++];
        }
        while(k <= right){
            temp[i++] = arr[k++];
        }
        for (int a = 0;a < temp.length;a++){
            arr[a+left] = temp[a];//理解为什么要arr[a+left],+left是为了定位当前归并的位置
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值