java 基础的算法

0 交换数组内的值

/**
     * 交换数组内的值
     * @param a
     * @param b
     * @param array
     */
    public static void swap(int a, int b, int[] array) {
        int temp = array[a];
        array[a] = array[b];
        array[b] = temp;
    }

1 冒泡排序

会一直改变原来的数据结构

/**
     * 冒泡排序
     * a b c d表示数组的位子上的数字,会发现变换
     * 第一轮:
     * 比较a和b,如果a大于b,那么交换a,b位子上的数字,接着比较b和c
     * 如果c大于b,那么不进行交换,接着比较c和d
     * 如果c的数字小于b,那么交换b和c位子上的数字,接着比较c和d
     * 第二轮:
     * 比较b和c ...
     * @param arr
     */
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; ++i) {
            for (int j = 0; j < arr.length -1 -i; ++i) {
                if (arr[j + 1] < arr[j]){
                    swap(j, j +1, arr);
                }
            }
        }
    }

2 快速排序

    /**
     * 快速排序
     * @param arr 需要进行排序的数组
     * @param low 需要排序的起始位置,我们一般填写0
     * @param high 需要排序的的结束位置,一般我们填写arr.length -1
     * 我们以第一数为基数a,先从最右边开始找到小于a的数字,记录下坐标a1
     * 接着从左边开始,找到大于a的值,记录下坐标a2,a1和a2的值进行交换
     * 再接着从右边刚刚等停止的位置上开始找小于a的位子,记录...
     * 最后当两个指针相遇的时候,交换相遇的位置的坐标点与基数的数字,
     * 现在基数已经归位,我们需要做的事情就是讲基数左边和右边的数,进行快速排序
     */
    public static void quickSort(int[] arr,int low,int high){
        int i, j, temp;
        if (low > high) {
            return;
        }
        i = low;
        j = high;
        //temp就是基准位
        temp = arr[low];
        while (i < j) {
            //先看右边,依次往左递减
            while (temp <= arr[j] && i < j) {
                j--;
            }
            //再看左边,依次往右递增
            while (temp >= arr[i] && i < j) {
                i++;
            }
            //如果满足条件则交换
            if (i < j) {
                swap(i, j, arr);
            }
        }
        //最后将基准为与i和j相等位置的数字交换
        arr[low] = arr[i];
        arr[i] = temp;
        //递归调用左半数组
        quickSort(arr, low, j-1);
        //递归调用右半数组
        quickSort(arr, j+1, high);
    }

3 选择排序

 /**
     * 选择排序:
     *  第一轮循环:假设第一个数a为最小值,比较后面的值的大小
     *  记录下比第一个数小的坐标(数为b),后面比较的是b与后面值得大小
     *  如果出现了比b小的数c,那么记录坐标,并且将c与后面的数比较大小
     *  运行到最后,可以将第一个数与记录下的最小那个数进行交换
     *  第二轮循环:假设第二个数为最小值,....
     * @param array
     */
    public static void selectSort(int[] array) {
        for(int i = 0; i < array.length; ++i) {
            int index = i;
            for(int j = i +1; j < array.length; ++j){
                if(array[j] < array[index]){
                    index = j;
                }
            }
            if(i != index) {
                swap(i, index, array);
            }
        }

    }

4 插入排序

 /**
     * 插入排序
     * a b c 表示所处的位置
     * 第一步:比较前面两个的数字a和b的大小,将小的放置在前面
     * 第二步:比较c与b的大小,小的话进行交换,并且再次比较a的大小,
     * 如果大于b,那么就不需要去b比较a的位子
     * 第三步: 比较d:....
     * @param array
     */
    public static void insertSort(int[] array){
        for(int i = 1; i < array.length; ++i){
            for(int j = i; j > 0; j--){
                if(array[j] < array[j - 1]){
                    swap(j, j - 1, array);
                }else{
                    break;
                }
            }
        }
    }

5 Shell排序

 /**
     * 希尔排序
     * 时间复杂度: O(n1.3)
     * 空间复杂度:
     * 稳定性: 不稳定 如[5,5,3,3]
     * 假设我们的数组为[6,4,2,7,3,1,8,5,9]
     * 首先将取得增量,增量的来源是数组长度除以2,得到的增量表示4, 2 , 1
     * 那么一开始比较的是6/3, 4/1, 2/8, 7/5, 6/9,得到的数组是【3, 1, 2, 5, 6, 4, 8, 7, 9】
     * 接着比较的是3/2, 1/5, 2,/6, 5/4, 6/8, 5/7, 8/9 得到的数组为【2, 1 , 3, 4 , 6, 5, 8 , 7 , 9】
     * 最后就是两两的相互比较。
     * @param arr
     */
    public static void shellSort(int[] arr){
        // d 表示增量7 3 1
        for(int d = arr.length / 2; d > 0; d /= 2) {
            for(int i = d; i < arr.length; ++i) {
                for(int j = i - d ; j >= 0; j -= d) {
                    if(arr[j] > arr [j + d]) {
                        swap(j, j +d , arr);
                    }
                }
            }
        }
    }

6 堆排序

public static void heapSort(int[] array){
        //建堆
        initHeap(array);

        int count = array.length;
        while(count > 1) {
            int tmp = array[count - 1];
            array[count - 1] = array[0];
            array[0] = tmp;

            count--; //未排序部分又少一个
            //调整过程自上而下,参数root=0
            adjustHeap(array, count, 0);
        }
    }

    public static void initHeap(int[] array){
        //建堆,从最后一个非叶子节点开始,而最后一个非叶子节点的下标为array.length/2-1
        for(int root = array.length/2 - 1; root >= 0; root--){
            adjustHeap(array, array.length, root);
        }

    }


    public static void adjustHeap(int[] array, int count, int root){
        int maxChildIndex;
        //待调整子堆的根节点必须是非叶子节点
        while(root <= count/2-1) {
            //需要在root、letfchild、rightchild中找到最大的值,
            //因为最后一个非叶子节点有可能没有右孩子,所以要做出判断。
            if(root == count/2 - 1 && count % 2 == 0){
                //节点数量为偶数时,最后一个非叶子节点只有左孩子
                maxChildIndex = 2 * root + 1;
            }else{
                int leftChildIndex = 2 * root + 1;
                int rightChildIndex = 2 * root + 2;

                maxChildIndex = array[leftChildIndex] > array[rightChildIndex] ?
                        leftChildIndex : rightChildIndex;
            }

            if(array[root] < array[maxChildIndex]){
                Swap.swap(root,maxChildIndex,array);
                //*****************这里很重要,继续调整因交换结构改变的子堆
                root = maxChildIndex;
            }else{
                return;
            }
        }
    }

66 参考的资料

堆排序资料

99 项目地址

GitHub地址1
GitHub地址2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值