【202309】算法基础-B01-排序算法

(注:实验一请同学们自主学习完成,以下代码仅供参考)

实验目的

  • 探索不同排序算法在不同数据量下的时间效率
  • 探索排序算法的稳定性
  • 掌握快速排序partition的双指针算法
  • 掌握归并排序的合并算法

代码示例


import java.util.Scanner;

// 排序算法解决方案: SortingSolution 
public class SortingSolution {
    // 比较两个数组元素大小
    int comp(int a, int b) { return Integer.compare(a, b); }

    // 交换数组元素
    void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; }

    // 1. 冒泡排序
    void bubbleSort(int[] a) {
        int bound, exchange = a.length - 1;
        while (exchange != 0) {
            bound = exchange;
            exchange = 0;
            for (int i = 0; i < bound; i++) 
                if (comp(a[i], a[i + 1]) > 0) {
                    swap(a, i, i + 1);
                    exchange = i;
                }
        }
    }

    // 2. 选择排序
    void selectSort(int[] a) {
        for (int i = 0; i < a.length - 1; i++) {
            int index = i;
            for (int j = i + 1; j < a.length; j++) 
                if (comp(a[j], a[index]) < 0)
                    index = j;
            if (index != i)
                swap(a, i, index);
        }
    }

    // 3. 插入排序
    void insertSort(int[] a) {
        for (int i = 1; i < a.length; i++) {// 从第 2 个记录开始执行
            int t = a[i], j = i - 1;        // 将待插入元素暂存于变量 t 
            for (; j >= 0 && t < a[j]; j--) // 搜索插入位置,注意不要越界
                a[j + 1] = a[j];            // 记录后移
            a[j + 1] = t;                   // 完成 t 的插入操作
        }
    }

    // 4. 归并排序
    int[] mergeSort(int[] a, int left, int right) {
        // 边界条件:没有元素或 1 个元素直接返回
        if (left > right) return new int[0];
        if (left == right) return new int[] { a[left] };

        // 划分并求解子问题
        int mid = left + (right - left) / 2;
        int[] a1 = mergeSort(a, left, mid);
        int[] a2 = mergeSort(a, mid + 1, right);

        // 合并
        int[] c = new int[a1.length + a2.length]; 
        int i1 = 0, i2 = 0;
        while (i1 < a1.length && i2 < a2.length) {
            if (a1[i1] <= a2[i2]) {
                c[i1 + i2] = a1[i1];
                i1++;
            } else {
                c[i1 + i2] = a2[i2];
                i2++;
            }
        }

        // 不要忘记对子数组的剩余部分进行合并

        while (i1 < a1.length) {
            c[i1 + i2] = a1[i1];
            i1++;
        }

        while (i2 < a2.length) {
            c[i1 + i2] = a2[i2];
            i2++;
        }

        return c;
    }

    // 5. 快速排序
    void quickSort(int[] a, int p, int r) {
        if (p < r) {
            int q = partition(a, p, r); // 划分,并返回轴值在数组中的位置
            quickSort(a, p, q - 1);     // 递归求解左子数组
            quickSort(a, q + 1, r);     // 递归求解右子数组
        }
    }

    // (快速排序核心算法)对 a[p..r] 进行划分操作
    int partition(int[] a, int p, int r) {
        int pivot = a[p];   // 选定轴值
        int i = p, j = r;   // 初始化左右指针
        while (i < j) {
            while (i < j && pivot <= a[j])
                j--;
            if (i < j) {
                swap(a, i, j);
                i++;
            }
            while (i < j && pivot >= a[i])
                i++;
            if (i < j) {
                swap(a, i, j);
                j--;
            }
        }
        return i;
    }

    // 测试:应用排序算法对序列进行排序
    int[] testSort(int[] a, int select) {
        // 调用其中一种排序算法:
        switch (select) {
            case 1:
                bubbleSort(a); // 冒泡排序
                break;
            case 2:
                selectSort(a); // 选择排序
                break;
            case 3:
                insertSort(a); // 插入排序
                break;
            case 4:
                a = mergeSort(a, 0, a.length - 1);    // 归并排序
                break;
            case 5:
                quickSort(a, 0, a.length - 1); // 快速排序
                break;
            default:
                System.out.println("不存在选项为" + select + "的排序算法!");
                a = new int[] { -1 };
        }
        return a;
    }

    // 打印数组到输出终端
    static String display(int[] a, int i) {
        return i == a.length - 1 ? "" + a[i]: 
            String.format("%d\t%s", a[i], display(a, i + 1));
    }

    public static void main(String[] args) {
        System.out.println("1.冒泡排序 2.选择排序 3.插入排序 4.归并排序 5.快速排序");
        System.out.print("请选择排序算法(1-5): ");
        Scanner scan = new Scanner(System.in);
        int s = scan.nextInt();
        scan.close();

        int[] a = { 49, 12, 54, 96, 26, 37, 48, 64 };
        System.out.println("排序前:" + display(a, 0));
        SortingSolution sln = new SortingSolution();
        a = sln.testSort(a, s);
        System.out.println("排序后:" + display(a, 0));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值