Java8大排序

8大排序学习(面试必备手写)

3个基本排序

冒泡排序
public static void BubbleSort(int[] arr){
		int temp = 0;
        for(int i = 0;i < arr.length - 1;i++){
            for(int j = i + 1;j < arr.length;j++){
                if(arr[i] > arr[j]){
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
}
选择排序
public static void selectSort(int[] arr){

        for(int i = 0;i < arr.length - 1;i++){
            int min = arr[i];
            int minIndex = i;
            for(int j = i + 1;j < arr.length;j++){
                if (min > arr[j]){
                    min = arr[j];
                    minIndex = j;
                }
            }
            if (minIndex != i){
                arr[minIndex] = arr[i];
                arr[i] = min;
            }
        }

}
插入排序
public static void insertSort(int[] arr){
        int insertVal = 0;
        int index = 0;
        for(int i = 1;i < arr.length;i++){
             insertVal= arr[i];
             index= i - 1;//从该位的前一位开始比较
//            if (arr[i] < arr[i - 1]){
                while (index >= 0 && insertVal < arr[index]){
                    arr[index + 1] = arr[index];
                    index--;
                }
//            if(index + 1 != i){
                arr[index + 1] = insertVal;
//            }
//            }
        }
}

进阶排序

希尔排序
	//希尔排序的交换法
    public static void shellChange(int[] arr){
        int temp = 0;
        for(int gap = arr.length/2;gap > 0;gap /= 2){
            for(int i = gap;i < arr.length;i++){
                for (int j = i - gap;j >= 0;j -= gap){
                    if (arr[j] > arr[j + gap]){
                        temp = arr[j];
                        arr[j] = arr[j + gap];
                        arr[j + gap] = temp;
                    }
                }
            }
        }
    }


    //希尔排序的移动法
    public static void shellMove(int[] arr){
        for(int gap = arr.length / 2;gap > 0;gap /= 2){
            for(int i = gap;i < arr.length;i++){
                int index = i - gap;
                int insertVal = arr[i];
                while (index >= 0 && insertVal < arr[index]){
                    arr[index + gap] = arr[index];
                    index -= gap;
                }
                arr[index + gap] = insertVal;
            }
        }
    }
快速排序
public static void quickSort(int[] arr,int left,int right){
        int pivot = arr[(left + right)/2];
        int l = left;
        int r = right;
        int temp = 0;//临时变量
        while(l < r){
            while (arr[l] < pivot){
                l++;
            }

            while (arr[r] > pivot){
                r--;
            }
            if(l >= r){
                break;
            }
            temp = arr[l];
            arr[l] = arr[r];
            arr[r] = temp;

            if(arr[l] == pivot){
                r--;
            }
            if(arr[r] == pivot){
                l++;
            }
        }

        if (l == r){
            l++;
            r--;
        }
        if (left < r){
            quickSort(arr,left,r);
        }
        if (right > l){
            quickSort(arr,l,right);
        }
}
归并排序
	//分+合方法
    public static void mergeSort(int[] arr,int left,int right,int[] temp){
        if(left < right){
            int mid = (left + right) / 2;
            //向左递归进行分解
            mergeSort(arr,left,mid,temp);
            //向右递归进行分解
            mergeSort(arr,mid + 1,right,temp);
            //合并
            mergeSort(arr,left,mid,right,temp);
        }
    }

    /**
     *
     * @param arr 排序的原始数组
     * @param left 左边有序序列的初始索引
     * @param mid 中间索引
     * @param right 右边索引
     * @param temp 做中转的数组
     */
    public static void mergeSort(int[] arr,int left,int mid,int right,int[] temp){
        int i = left;//初始化i,左边有序序列的初始索引
        int j = mid + 1;//初始化j,右边有序序列的初始索引
        int t = 0;//指向temp数组的当前索引

        //(一)
        //先把左右两边(有序)的数据按照规则填充到temp数组
        //知道左右两边的有序序列,有一边处理完毕为止
        while (i <= mid && j <= right){
            if(arr[i] <= arr[j]){
                temp[t] = arr[i];
                i++;
                t++;
            } else {
                temp[t] = arr[j];
                j++;
                t++;
            }
        }

        //(二)
        //把有剩余数据的一边的数据依次全部填充到temp
        while (i <= mid){
            temp[t] = arr[i];
            i++;
            t++;
        }

        while (j <= right){
            temp[t] = arr[j];
            j++;
            t++;
        }

        //(三)
        //将temp数组的元素拷贝到arr
        //注意,并不是每次都拷贝所有
        t = 0;
        int tempLeft = left;
        //
        while (tempLeft <= right){
            arr[tempLeft] = temp[t];
            t++;
            tempLeft++;
        }

    }
基数排序
	public static void radixSort(int[] arr){
        //首先,第一步,需要求得所有数中的最大值
        int max = arr[0];//我先假设arr[0]为最大的值
        for(int i = 0;i < arr.length;i++){
            if(max < arr[i]){
                max = arr[i];
            }
        }
        //循环完后,得到了最大值,就可以通过这个数算出最大的数的位数
        int weiShu = (max + "").length();

        //而位数,就是基数排序大循环的次数:每次,就是对应每位的运算。
        //运算之前,需要造10个桶,故:0-9,表示位数
        int[][] bucket =new int[10][arr.length];
        //bucketCount用来记录每个位数的桶上的存储数量
        int[] bucketCount = new int[10];

        for(int i = 0,n = 1;i < weiShu;i++,n *= 10){
            //1.首先需要将原来数组中的所有值装进对应的桶之中(按照每个循环对应的位数)
            for(int j = 0;j < arr.length;j++){
                int bitCount = arr[j] / n % 10;
                bucket[bitCount][bucketCount[bitCount]] = arr[j];
                bucketCount[bitCount]++;
            }
            int index = 0;
            //2.然后,将桶中的数,按照规则排序回原来的数组。
            for(int j = 0;j < bucket.length;j++){
                if(bucketCount[j] != 0){
                    for(int z = 0;z < bucketCount[j];z++){
                        arr[index++] = bucket[j][z];
                        //将bucket置零,下次排序才能进行
                        bucket[j][z] = 0;//可有可无
                    }
                }
                //将bucketCount置零,下一次排序才能进行
                bucketCount[j] = 0;
            }
        }
    }
堆排序(前置条件:顺序存储二叉树,堆)
	public static void heapSort(int[] arr){
        int temp = 0;
        //将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆
        for (int i = arr.length/2 - 1;i >= 0;i--){
            heapSort(arr,i,arr.length);
        }
        //将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
        //重新调节结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,
        // 反复执行调整 + 交换步骤,直到整个序列有序。
        for (int j = arr.length - 1;j > 0;j--){
            temp = arr[j];
            arr[j] = arr[0];
            arr[0] = temp;
            heapSort(arr,0,j);
        }
    }

    /**
     * 功能:完成 将 以 i 对应的非叶子节点的树调整成大顶堆
     * 举例: int[] = {4,6,8,5,9}; => i = 1 => adjustHeap => 得到{4,9,8,5,6}
     * 如果我们再次调用 adjustHeap 传入的是i = 0 => 得到{4,9,8,5,6} => {9,6,8,5,4}
     * @param arr 待调整的数组
     * @param i 表示非叶子节点在数组中索引
     * @param length 表示对多少个元素继续调整,length 是在逐渐的减少
     */
    public static void heapSort(int[] arr,int i,int length){
        int temp = arr[i];//先取出当前元素的值,保存在临时变量
        //开始调整
        //1. k = i * 2 + 1 k 是 i节点的左子节点
        for (int k = i * 2 + 1;k < length;k = k * 2 + 1){
            if (k + 1 < length && arr[k] < arr[k + 1]){//说明左子节点的值小于右子节点的值
                k++;//k 指向右子节点
            }
            if (arr[k] > temp){//如果子节点大于父节点
                arr[i] = arr[k];//把较大的值赋给当前节点
                i = k;//!!!  i 指向k,继续循环比较


            } else {
                break;
            }
        }
        //当for 循环结束后,我们已经将以i 为父节点的树的最大值,放在了 最顶(局部)
        arr[i] = temp;//将temp值放到调整后的位置

    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人山人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值