八个排序算法实现

package sort.demo;

import java.util.Arrays;
import java.util.Calendar;

public class SortDemo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        /*
         * ```````````````````````插入式排序~~~~~~~~~~~~~~~~~
         */
        // 直接插入排序算法实例
        // insertSort(new int[] { 32, 2342, 234, 12, 34, 5, 67, 8 });
        // insertBinarySort(new int[] { 32, 2342, 234, 12, 34, 5, 67, 8 });
        int[] ints = new int[] { 32, 2342, 234, 2, 90, 1, 5, 67, 8, 35, 122, -23 };
        // Print(ints);
        // // 希尔排序
        // shellSort(ints);
        // Print(ints);
        //
        // /*
        // * 交换式排序
        // */
        // bubbleSort(new int[] { 32, 2342, 234, 12, 1, 5, 67, 8, 35, 122, -23
        // });
        System.out.println("选择排序");
        GetSystemTime();
        Print(ints);
        selectSort(ints);
        Print(ints);
        GetSystemTime();
        System.out.println("开始堆排序");
        GetSystemTime();
        int[] ps = new int[] { 81, 49, 38, 27, 97, 76, 19, 13 };
        Print(ps);
        heapSort(ps);
        Print(ps);
        GetSystemTime();
        ps = new int[] { 81, 49, 38, 27, 97, 76, 19, 13 };
        Print(mergeSort(ps));

    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~归并排序
     */

    public static int[] mergeSort(int[] nums) {
        if (nums == null) {
            return null;
        }
        return mergeSort(nums, 0, nums.length - 1);

    }

    /**
     * 归并排序
     * 
     * @param nums
     * @param low
     * @param high
     *            数组下标的上限
     * @return
     */
    public static int[] mergeSort(int[] nums, int low, int high) {
        int mid = (high - low) / 2 + low;
        if (low < high) {
            // 左边
            mergeSort(nums, low, mid);
            // 右边
            mergeSort(nums, mid + 1, high);
            // 左右归并
            merge(nums, low, mid, high);
        }
        return nums;
    }

    /**
     * 归并操作
     * 
     * @param nums
     * @param low
     * @param mid
     * @param high
     */
    private static void merge(int[] nums, int low, int mid, int high) {
        // 新的带缓存的数组
        int[] temp = new int[high - low + 1];
        int i = low;// 左指针
        int j = mid + 1;// 右指针
        int k = 0;

        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }

        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = nums[i++];
        }

        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = nums[j++];
        }

        // 把新数组中的数覆盖nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            nums[k2 + low] = temp[k2];
        }
    }

    /**
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~`~~~选择排序~~~~~~~~~~~~~~~~~~
     * 
     */
    /**
     * 直接选择排序,每次选择i位置的为最小,然后跟i到n-1位置的元素比较,如果更小,更新min=i,遍历完了之后 交换min和i位置处的元素值
     * 
     * @param table
     */
    public static void selectSort(int[] table) {
        for (int i = 0; i < table.length - 1; i++) {
            int min = i;
            for (int j = i + 1; j < table.length; j++)
                if (table[j] < table[min])
                    min = j;
            if (min != i) {
                int temp = table[i];
                table[i] = table[min];
                table[min] = temp;
            }

            System.out.print("第" + i + "次选择排序");
            Print(table);
        }
    }

    /**
     * 关于堆排序有错误
     * 
     * @param table
     */
    public static void heapSort(int[] table) {
        if (table == null)
            return;
        int temp;
        int length = table.length;
        // 依据序列构建最小堆
        for (int i = length / 2 - 1; i >= 0; i--) {
            shift(table, i, length - 1);
        }
        Print(table);
        for (int j = length - 1; j > 0; j--) {
            temp = table[0];
            table[0] = table[j];
            table[j] = table[0];
            shift(table, 0, j - 1);
        }
    }

    private static void shift(int[] table, int begin, int end) {
        // TODO Auto-generated method stub
        int i = begin, j = 2 * i + 1;
        int temp = table[i];
        while (j <= end) {
            if ((j < end) && (table[j] > table[j + 1]))
                j++;// end最大为n-1,只有当j最大为n-2时候,才执行这个判断语句,寻找子节点最小编号
            if (temp > table[j]) {
                table[i] = table[j];

                i = j;
                j = 2 * i + 1;
            } else {

                break;
            }

        }
        table[i] = temp;

    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~交换式排序~~~~~~~~~~~~~~~~`
     */
    /**
     * 冒泡排序
     * 
     * @param table
     */
    public static void bubbleSort(int[] table) {
        boolean exchange = true;// 一趟比较下来是否交换的标记
        for (int i = 1; i < table.length && exchange; i++) {// 总共比较n-1趟,每趟使得的最大值在沉入数组下面
            exchange = false;// 标记还没有交换
            for (int j = 0; j < table.length - i; j++) // 每趟比较n-i次
                if (table[j] > table[j + 1]) {
                    int temp = table[j];
                    table[j] = table[j + 1];
                    table[j + 1] = temp;
                    exchange = true;
                }
        }
    }

    public static void quickSort(int[] table) {
        quickSort(table, 0, table.length - 1);

    }

    private static void quickSort(int[] table, int begin, int end) {
        // TODO Auto-generated method stub
        // 序列要有效
        if (begin < end) {
            int L = begin, R = end;
            int base = table[R];// 基准值去最右边的一个值
            // 开始一趟遍历
            while (L != R) {
                while (L < R && table[L] <= base)// 从数组左边开始遍历
                    L++;
                if (L < R)
                    table[R--] = table[L];
                while (L < R && table[R] >= base) // 从数组右边开始遍历
                    R--;
                if (L < R)
                    table[L++] = table[R];
            }
            table[L] = base;// 将基准值赋值到准确位置,是的基准值左边的所有数都是小于基准值,右边的数都大于基准值
            // 下面对左右两个子序列递归
            quickSort(table, begin, L - 1);
            quickSort(table, L + 1, end);

        }
    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~插入式排序~~~~~~~~~~~~~~~~~~~~~``
     */
    /**
     * 以对int关键字的插入排序, 插入排序的关键点是,每趟只是插入一个关键字到一个有序的序列中 对于n个元素的数组需要n-1趟扫描插入
     * 
     * @param table
     */
    public static void insertSort(int[] table) {
        // 下标从1开始到,i表示当前带插入的元素
        Print(table);
        for (int i = 1; i < table.length; i++) {
            int temp = table[i], j;
            // 数组前0到i-1位置元素都是有序的且是递增的
            for (j = i - 1; j >= 0 && temp < table[j]; j--)
                table[j + 1] = table[j];
            table[j + 1] = temp;
            System.out.print("第" + i + "次插入  ");
            Print(table);

        }
    }

    /**
     * 折半插入排序只是减少了寻找插入位置的寻找次数,但是找到了插入位置后移动元素的位置还是一样那么多 。计算过程:对于插入第i个元素,计算 0 ~
     * i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素相比中间节点大,
     * 说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置
     * 到中间值的位置,这样很简单的完成了折半;确定位置之后,将整个序列后移,并将元素插入到相应位置
     * 
     * @param arr
     * @return
     */
    private static int[] insertBinarySort(int[] arr) {
        int temp, hight, low;
        for (int i = 1; i < array.length; i++) {
            temp = array[i];
            hight = i - 1;
            low = 0;
            int middleIndex;// 待比较元素下标
            int locationIndex = hight;// 记录插入位置
            // 折半查找插入位置locationIndex
            while (low <= hight) {
                middleIndex = ((hight - low) / 2) + low;
                if (array[middleIndex] > temp) {
                    hight = middleIndex - 1;
                    locationIndex = hight;
                } else if (array[middleIndex] < temp) {
                    low = middleIndex + 1;
                    locationIndex = low;
                } else {
                    locationIndex = middleIndex;
                    break;
                }

            }
            // 修改下loctionIndex越出两边边界情况
            if (locationIndex < 0) {
                locationIndex = 0;
            } else if (locationIndex >= i) {
                locationIndex = i;
            }
            // 将从locationIndex位置到 i-1位置的元素都移动
            for (int j = i - 1; j >= locationIndex; j--) {
                array[j + 1] = array[j];
            }
            array[locationIndex] = temp;
        }
        return array;
    }

    /*
     * 0 1 2 3 4 5 6 7 8 9 32, 2342, 234, 12, 1, 5, 67, 8, 35, 122 插入式排序算法-希尔排序
     * 希尔排序算法的思想是我对一个关键字序列进行分组,每组上面进行直接插入排序
     * 这里分组是分为序列长度的一半,然后对每个分组构成一个虚拟的序列,在对这个序列插入排序
     */
    public static void shellSort(int[] table) {
        for (int delta = table.length / 2; delta > 0; delta /= 2) {// delta是分组的组数,先对半在对半,直到最后一组在进行一次插入排序
            for (int i = delta; i < table.length; i++) {
                // 分成delta组,下面是对分组进行插入排序
                int temp = table[i], j;
                for (j = i - delta; j >= 0 && temp < table[j]; j -= delta)
                    table[j + delta] = table[j];
                table[j + delta] = temp;
            }
            Print(table);
        }

    }

    /*
     * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~工具类
     */
    public static void GetSystemTime() {
        Calendar cal = Calendar.getInstance();
        System.out.println(cal.getTime());
    }

    private static void Print(int[] table) {
        // TODO Auto-generated method stub
        for (int i = 0; i < table.length; i++)
            System.out.print(table[i] + " ");

        System.out.println();
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值