内部排序法的代码实现

冒泡排序

     * 冒泡排序需要比较 n(n-1)/2次,时间复杂度O(n^2)
     * 稳定排序
     * 只需额外一个空间,空间复杂度最佳
     * 适用于数据量小或有部分数据已经排过序的情况
     *
     * 不管数据是否已经完成排序都要执行 n(n-1)/2次
public class BubbleSort {
    public static void main(String[] args) {
       

        /**结果:
         * 冒泡排序法======================
         * 原始数据为: 6 5 9 7 2 8
         * 第1次排序后的结果是: 5 6 7 2 8 9
         * 第2次排序后的结果是: 5 6 2 7 8 9
         * 第3次排序后的结果是: 5 2 6 7 8 9
         * 第4次排序后的结果是: 2 5 6 7 8 9
         * 第5次排序后的结果是: 2 5 6 7 8 9
         * 排序后的结果是: 2 5 6 7 8 9
         */

        int i, j ,temp;
        int data[] = {6, 5, 9, 7, 2, 8};
        System.out.println("冒泡排序法======================");
        System.out.print("原始数据为: ");
        for (i = 0; i < data.length; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();

        for(i = 5; i > 0; i--){             //扫描次数
            for(j = 0; j < i; j++){         //比较、交换次数
                //比较相邻的两数字,前面的大就交换
                if (data[j] > data[j+1]) {
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                }
            }
            //各次扫描后的结果打印
            System.out.print("第" + (6-i) + "次排序后的结果是: ");
            for(j = 0; j < data.length; j++){
                System.out.print(data[j] + " ");
            }
            System.out.println();
        }

        System.out.print("排序后的结果是: ");
        for (i = 0; i < data.length; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();

    }
}

冒泡排序增强

 * 改良的冒泡排序法
 * 普通的冒泡不管数据是否已经完成排序都要执行 n(n-1)/2次
public class BubbleSortPro {
 

    int[] data = new int[] {4, 6, 2, 7, 8, 9};

    public static void main(String[] args) {
        System.out.print("改良的冒泡排序法\n原始数据为: ");
        BubbleSortPro test = new BubbleSortPro();
        test.showData();
        test.bubblePro();

    }

    /**结果:
     * 改良的冒泡排序法
     * 原始数据为: 4 6 2 7 8 9
     * 第1次排序后的结果是: 4 2 6 7 8 9
     * 第2次排序后的结果是: 2 4 6 7 8 9
     * 排序结果为: 2 4 6 7 8 9
     */


    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < 6; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void bubblePro() {
        int i, j, temp, flag;
        for(i = 5; i > 0; i--){
            flag = 0;//用来判断是否有交换动作
            for (j = 0; j < i; j++){
                if (data[j] > data[j+1]) {
                    temp = data[j];
                    data[j] = data[j+1];
                    data[j+1] = temp;
                    flag ++;        //如果有执行过交换,则flag != 0;
                }
            }
            if(flag == 0){
                break;
            }

            //当执行完一次扫描就判断是否做过交换动作,如果没有则表示已经完成排序,故可直接跳出循环
            System.out.print("第" + (6-i) + "次排序后的结果是: ");
            for(j = 0; j < data.length; j++){
                System.out.print(data[j] + " ");
            }
            System.out.println();
        }
        System.out.print("排序结果为: ");
        showData();
    }
}

堆积排序法

 *堆积排序法分析  选择排序的改进
 * 二叉树的技巧
 * 大->小  最大堆积树   根节点大先取出
 * 小->大  最小堆积树   根节点小先取出
 *
 * 所有情况下,时间复杂度均为O(n log10为底 n)
 * 不稳定
 * 只需额外一个空间,空间复杂度O(1)
public class HeapSort {
    
    public static void main(String[] args) {

        int i, size, data[] = {0, 5, 6, 4, 8, 3, 2, 7, 1};
        size = 9;
        System.out.print("原始数组:");
        for (i = 1 ; i < size; i++){
            System.out.print("[" + data[i] +"]");
        }
        System.out.println();
        Heapsort.heap(data, size);
        System.out.print("\n排序结果: ");
        for (i = 1; i < size; i++){
            System.out.print("[" + data[i] + "]");
        }
        System.out.println();


    }
    public static void heap(int data[], int size){
        int i, j ,temp;
        for (i = (size/2); i > 0; i--){                 //建立堆积树节点
            Heapsort.adHeap(data, i, size-1);
        }
        System.out.print("\n堆积内容:");
        for (i = 1; i < size; i++){                     //原始堆积树内容
            System.out.print("[" + data[i] + "]");
        }
        System.out.println();

        for (i = size-2; i > 0; i--){                   //堆积排序
            temp = data[i+1];                           //头尾节点交换
            data[i+1] = data[1];
            data[1] = temp;
            Heapsort.adHeap(data, 1, i);              //处理剩余节点
            System.out.print("\n处理过程: ");
            for (j = 1; j < size; j++){
                System.out.print("[" + data[j] + "]");
            }

        }
    }
    public static void adHeap(int data[], int i, int size){
        int j, temp, post;
        j = 2*i;
        temp = data[i];
        post = 0;
        while (j <= size && post == 0){
            if(j < size){
                if(data[j] < data[j+1]){                //找出最大节点
                    j++;
                }
            }
            if(temp >= data[j]){                        //若树根较大,结束比较
                post = 1;
            }else {                                     //若树根较小,则继续比较
                data[j/2] = data[j];
                j *= 2;
            }
        }
        data[j/2] = temp;                               //指定树根为父节点
    }

}

插入排序法

 * 插入排序法分析
 * 比较次数 n(n-1)/2次 时间复杂度 O(n^2)
 * 稳定排序
 * 只需额外一个空间,空间复杂度最佳
 * 适用于大部分数据已经排过序或已排序数据库新增数据后进行排序的情况
 * 插入排序会造成数据的大量搬移,所以建议链表使用
public class InsertionSort {

    int[] data = new int[6];
    int size = 6;
    public static void main(String[] args) {

        InsertionSort test = new InsertionSort();
        test.inputarr();
        System.out.print("您输入的原始数组是:");
        test.showData();
        test.insert();

    }

    public void inputarr() {
        int i;
        for(i = 0; i < size; i++){

            try {
                System.out.println("请输入第" + (i+1) + "个元素:");
                InputStreamReader isr = new InputStreamReader(System.in);
                BufferedReader br = new BufferedReader(isr);
                data[i] = Integer.parseInt(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < size; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void insert(){
        int i, j, temp;         //i 为扫描次数,j 为定位比较元素, temp暂存数据
        for(i = 1; i <size; i++){   //扫描次数为SIZE - 1
            temp = data[i];
            j = i-1;
            while (j >= 0 && temp < data[j]){
                data[j+1] = data[j];
                j--;
            }
            data[j+1] = temp;
            System.out.println("第" + i + "次扫描:");
            showData();
        }
    }
}

快速排序法

 * 快速排序法分析   又叫分隔交换排序法’
 * 最快及平均的时间复杂度为O(nlog2为底 n) 最坏就是每次挑中的中间值不是最大就是最小,时间复杂度为O(n^2)
 * 不稳定
 * 最差空间复杂度为O(n) 最好O(log2为底 n)
 * 平均运行时间最快的排序法
public class QuickSort {

    int process = 0;
    int size;
    int[] data = new int[100];
    public static void main(String[] args) {

        QuickSort test = new QuickSort();
        System.out.print("请输入数组的大小(100以下):");
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            test.size = Integer.parseInt(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        test.inputarr();
        System.out.print("原始数组数据是;");
        test.showData();

        test.quick(test.data, test.size, 0, test.size-1);
        System.out.print("\n排序结果是:");
        test.showData();

    }

    public void inputarr(){     //随机输入
        Random rand = new Random();
        int i;
        for(i = 0; i < size; i++){
            data[i] = (Math.abs(rand.nextInt(99)))+1;
        }
    }

    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < size; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void quick(int d[], int size, int lf, int rg){
        int i, j, temp;
        int lfIdx, rgIdx;
        int t;


        if(lf < rg){                //1: 第一个键值为d[lf]
            lfIdx = lf+1;
            rgIdx = rg;
            //排序
            while(true){
                System.out.print("[处理过程" + (process++) + "]=>");
                for (t = 0; t < size; t++){
                    System.out.print("[" + d[t] + "] ");
                }
                System.out.println();
                for(i = lf+1; i <= rg; i++){        //2:从左向右找出一个键值大于d[lf]者
                    if(d[i] >= d[lf]){
                        lfIdx = i;
                        break;
                    }
                    lfIdx++;
                }
                for(j = rg; j >= lf+1; j--){        //3:从右向左找出一个键值小于d[lf]者
                    if(d[j] <= d[lf]){
                        rgIdx = j;
                        break;
                    }
                    rgIdx--;
                }
                if(lfIdx < rgIdx){                      //4-1:若lfIdx<rgIdx,
                    temp = d[lfIdx];
                    d[lfIdx] = d[rgIdx];            //则d[lfIdx] 和 d[rgIdx] 互换
                    d[rgIdx] = temp;                //然后继续排序
                }else {
                    break;                          //否则跳出循环
                }
            }
            //整理
            if(lfIdx >= rgIdx){                     //5-1:若lfIdx>=rgIdx,
                temp = d[lf];
                d[lf] = d[rgIdx];                   //则d[lfIdx] 和 d[rgIdx] 互换
                d[rgIdx] = temp;
                                                    //5-2:以rn=gIdx 为基准点分成左右两半
                quick(d, size, lf, rgIdx-1);    //以递归方式分别将左右两半进行排序
                quick(d, size, rgIdx+1, rg);     //直至排序完成
            }

        }
    }


}

基数排序法

 * 基数排序法分析
 * 按照最高为优先:最左边的位数开始比较   最低为优先:最右边的位数开始比较  两种
 * 在所有的情况下时间复杂度均为O(n log p为底 k),k为院原始数据最大值
 * 稳定
 * 很大的额外存储空间,空间复杂度O(n*p),n 是原始数据的个数,p 是数据字符数
 * 若n很大, p固定或者很小,则该方法很有效率
public class RadixSort {

    int size;
    int[] data = new int[100];
    public static void main(String[] args) {

        RadixSort test = new RadixSort();
        System.out.print("请输入数组的大小(100以下)");
        try {
            InputStreamReader isr = new InputStreamReader(System.in);
            BufferedReader br = new BufferedReader(isr);
            test.size = Integer.parseInt(br.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
        test.inputarr();
        System.out.print("原始数组数据是;");
        test.showData();
        test.radix();

    }
    public void inputarr(){     //随机输入
        Random rand = new Random();
        int i;
        for(i = 0; i < size; i++){
            data[i] = (Math.abs(rand.nextInt(999)))+1;//设定data最大为三位数
        }
    }
    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < size; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void radix(){
        int i, j ,k, n, m;
        for (n = 1; n <= 100; n *= 10){         //n为基数,由个位数开始排序
            //设定暂存数组,[0-9位数][数据个数], 所有内容均为0
            int[][] temp = new int [10][100];
            for (i = 0; i < size; i++){     //比较所有数据
                m = (data[i]/n) % 10;       //m为n位数的值,如36得到3
                temp[m][i] = data[i];       //把data[i]的值暂存在temp里面
            }
            k = 0;
            for (i = 0; i < 10; i++){
                for (j = 0; j < size; j++){
                    if (temp[i][j] != 0){   //因一开始设定temp = {0}, 故不为0即可
                        //data暂存在temp里面的值,把temp里面的值放回data[]里
                        data[k] = temp[i][j];
                        k++;
                    }
                }
            }
            System.out.print("经过" + n + "位数排序后: ");
            showData();
        }
    }
}

选择排序法

 *选择排序的分析
 * 比较次数 n(n-1)/2次 时间复杂度 O(n^2)
 * 不稳定
 * 只需额外一个空间,空间复杂度最佳
 * 适用于数据量小或有部分数据已经排过序的情况
public class SelectionSort {
   
    int[] data = new int[] {9, 7, 5, 3, 4, 6};

    public static void main(String[] args) {
        System.out.print("原始数据为: ");
        SelectionSort test = new SelectionSort();
        test.showData();
        test.select();

    }

    /**
     * 结果
     * 原始数据为: 9 7 5 3 4 6
     * 第1次排序后的结果是: 3 9 7 5 4 6
     * 第2次排序后的结果是: 3 4 9 7 5 6
     * 第3次排序后的结果是: 3 4 5 9 7 6
     * 第4次排序后的结果是: 3 4 5 6 9 7
     * 第5次排序后的结果是: 3 4 5 6 7 9
     * 排序结果为: 3 4 5 6 7 9
     */


    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < 6; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void select() {
        int i, j, temp, k;
        for(i = 0; i < 5; i++){         //扫描5次
            for(j = i+1; j < 6; j++){   //由i+1 比较起,比较5 次
                if(data[i] > data[j]){
                    temp = data[i];     //比较i 和 j 个元素   注意  i 对应的数据在交换后会变化
                    data[i] = data[j];
                    data[j] = temp;
                }
            }

            System.out.print("第" + (i+1) + "次排序后的结果是: ");
            for(k = 0; k < 6; k++){
                System.out.print(data[k] + " ");        //打印排序结果
            }
            System.out.println();
        }
        System.out.print("排序结果为: ");
        showData();
    }
}

希尔排序法

 * 希尔排序分析
 * 像插入排序,但可以减少次数,不同:将数据区分成特定间隔的几个小块,以插入排序法排完区块内的数据后再渐渐减少间隔的距离
 * 任何情况下时间复杂度都是 O(n ^3/2)
 * 稳定排序
 * 只需额外一个空间,空间复杂度最佳
 * 适用于大部分数据都已排序完成的情况
public class ShellSort {
  
    int[] data = new int[8];
    int size = 8;
    public static void main(String[] args) {

        ShellSort test = new ShellSort();
        test.inputarr();
        System.out.print("您输入的原始数组:");
        test.showData();
        test.shell();

    }

    public void inputarr() {
        int i;
        for(i = 0; i < size; i++){

            try {
                System.out.println("请输入第" + (i+1) + "个元素:");
                InputStreamReader isr = new InputStreamReader(System.in);
                BufferedReader br = new BufferedReader(isr);
                data[i] = Integer.parseInt(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    public void showData() {
        //利用循环打印数组
        int i;
        for (i = 0; i < size; i++){
            System.out.print(data[i] + " ");
        }
        System.out.println();
    }

    public void shell(){
        int i, j;       //i为扫描次数,j定位比较元素‘
        int k = 1;      //k 打印次数
        int temp;       //暂存数据
        int jmp;        //设定间隔位移量
        jmp = size / 2;
        while (jmp != 0){
            for(i = jmp; i < size; i++){
                temp = data[i];
                j = i-jmp;
                while (j >= 0 && temp < data[j]){       //插入排序
                    data[j + jmp] = data[j];
                    j = j-jmp;
                }
                data[jmp+j] = temp;
            }
            System.out.println("第" + (k++) + "次排序");
            showData();
            jmp /= 2;
        }
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值