算法:排序

定义

是将一组数据按照一定的规则排列起来,方便查询处理。

分类

  • 1内部排序
    图片来自网络
  • 2外部排序
    外部排序指的是大文件的排序,即待排序的记录存储在外存储器上,待排序的文件无法一次装入内存,需要在内存和外部存储器之间进行多次数据交换,以达到排序整个文件的目的。

1.1交换排序

  • 1.1.1冒泡排序
    基本思想:对排序记录数据从后往前(逆序)进行多次扫描,当发现相邻两个数据的次序与排序要求的规则不符实,就将这两个记录进行交换。这样,数据较小的记录将逐渐从后面向前面移动们就像气泡一样向上浮动,所以该算法称为冒泡排序法
public class BubbleSort {

    /**
     * @param args
     *            冒泡排序
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 36, 12, 89, 72, 8, 68 };
        ascendingBubbleSort(arr);// 升序
        for (int i : arr) {
            System.out.println(i); //输出
        }
    }

    /**
     * 降序
     * 
     * @param arr
     */
    static void descendingBubbleSort(int[] arr) {
        int temp;
        int m;
        //总共循环arr.length次
        for (int i = 0; i < arr.length; i++) {
            m = arr.length - i - 1;
            //每一次循环结束,此次循环最大数排到最后,减少一次循环
            for (int j = 0; j < m; j++) {
                if (arr[j] > arr[j + 1]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }

    /**
     * 升序
     * 
     * @param arr
     */
    static void ascendingBubbleSort(int[] arr) {
        int temp;
        //总共循环arr.length次
        for (int i = 0; i < arr.length; i++) {
            //每一次循环结束,此次循环最大数排到最前,减少一次循环
            for (int j = arr.length-1; j > i; j--) {
                if (arr[j] > arr[j - 1]) {
                    temp = arr[j];
                    arr[j] = arr[j - 1];
                    arr[j - 1] = temp;
                }
            }
        }
    }

}


  • 1.1.2快速排序
    基本思想:使用分治算法,把待排序数据序列分为两个子序列

操作步骤:
- 1.1.2.1 从数据中挑选一个元素,称该元素为“基准”;
- 1.1.2.2 扫描一遍数列,将所有比“基准”小的元素排在“基准”前面,所有比“基准”大的元素排在“基准”后面;
- 1.1.2.3 通过递归,将各子序列划分为更小的序列,直到把小于基准值元素的子序列和大于基准值元素的子序列排序。
public class QuickSort {

    /**
     * @param args
     *            快速排序
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 36, 12, 89, 72, 8, 68 };
        descendingQuickSort(arr, 0, arr.length - 1);
        for (int i : arr) {
            System.out.println(i); // 输出
        }
    }

    /**
     * 降序
     * 
     * @param arr
     * @param left
     * @param right
     */
    static void descendingQuickSort(int arr[], int left, int right) {
        if (left < right) {
            int divisionLeft = left, divisionRight = right;// 分割参数
            int base = arr[left];
            while (divisionLeft < divisionRight) {
                // 循环从右面找到小于于基准的数字
                while (divisionLeft < divisionRight
                        && arr[divisionRight] >= base)
                    divisionRight--;
                // 然后将数字赋值
                if (divisionLeft < divisionRight)
                    arr[divisionLeft++] = arr[divisionRight];

                // 循环从左面面找到第一个大于基准的数字

                while (divisionLeft < divisionRight && arr[divisionLeft] < base)
                    divisionLeft++;
                // 然后将数字赋值
                if (divisionLeft < divisionRight)
                    arr[divisionRight--] = arr[divisionLeft];
            }

            arr[divisionLeft] = base;// 当divisionLeft=divisionRight时赋值
            descendingQuickSort(arr, left, divisionLeft - 1);// 递归调用 基数左边
            descendingQuickSort(arr, divisionLeft + 1, right);// 递归调用 基数右边
        }
    }

    /**
     * 升序
     * 
     * @param arr
     * @param left
     * @param right
     */
    static void ascendingQuickSort(int arr[], int left, int right) {
        if (left < right) {
            int divisionLeft = left, divisionRight = right;// 分割参数
            int base = arr[left];
            while (divisionLeft < divisionRight) {
                // 循环从右面找到小于于基准的数字
                while (divisionLeft < divisionRight
                        && arr[divisionRight] <= base)
                    divisionRight--;
                // 然后将数字赋值
                if (divisionLeft < divisionRight)
                    arr[divisionLeft++] = arr[divisionRight];

                // 循环从左面面找到第一个大于基准的数字

                while (divisionLeft < divisionRight && arr[divisionLeft] > base)
                    divisionLeft++;
                // 然后将数字赋值
                if (divisionLeft < divisionRight)
                    arr[divisionRight--] = arr[divisionLeft];
            }

            arr[divisionLeft] = base;// 当divisionLeft=divisionRight时赋值
            ascendingQuickSort(arr, left, divisionLeft - 1);// 递归调用 基数左边
            ascendingQuickSort(arr, divisionLeft + 1, right);// 递归调用 基数右边
        }
    }
}

1.2选择排序

  • 1.2.1直接选择排序
    基本思想:通过对N个记录将其输出,选择最小的记录输出,再循环(N-1)次在输出最小值,直到只剩下一个记录。有点类似于冒泡
public class ChoiceSort {

    /**
     * @param args
     *            简单选择排序
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 36, 12, 89, 72, 8, 68 };
        choiceSort(arr);
        for (int i : arr) {
            System.out.println(i); // 输出
        }
    }

    static void choiceSort(int arr[]) {
        int temp;
        for (int i = 0; i < arr.length; i++) {
            for (int j = i; j < arr.length - 1; j++) {
                if (arr[i] > arr[j + 1]) {
                    temp = arr[i];
                    arr[i] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}


  • 1.2.2堆排序
    基本思想:堆就是一个完整的二叉树,树中每个结点对应于原始数据的一个记录,并且每个结点应满足以下条件,非叶结点的数据大于或者等于其左右孩子结点的数据

  • 将无序的数据构成堆(即用无序数据生成满足堆定义的完全二叉树);
  • 利用堆排序(即用上一步生成的堆输出有序的数据),即是对完全二叉树进行遍历。

1.3插入排序

  • 1.3.1直接插入排序(Insertion Sort)
    基本思想:通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
public class InsertionSort {

    /**
     * @param args
     *            插入排序
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 36, 12, 89, 72, 8, 68 };
        insertionSort(arr);
        for (int i : arr) {
            System.out.println(i); // 输出
        }

    }

    static void insertionSort(int arr[]) {

        int i,j,temp;
         for(i=1;i<arr.length;i++){
             temp =arr[i];//取出一个未排序的数据
             for(j = i-1;j>=0&& temp <arr[j];j--)//在排序序列中查找位置,<降序,>升序
                 arr[j+1]= arr[j];//向后移动数据
             arr[j+1] = temp;//插入数据带序列
         }
    }
}
  • 1.3.2希尔排序(Shell)
    基本思想:(缩小增量排序)将需要排序的序列划分为若干个较小序列,对这些序列进行直接插入排序,通过这样的操作可使用需要排序的数列基本有序,最后再使用一次直接插入排序。
public class ShellSort {

    /**
     * @param args
     *            希尔排序
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        int[] arr = { 36, 12, 89, 72, 8, 68 };
        shellSort(arr);
        for (int i : arr) {
            System.out.println(i); // 输出
        }
    }

    static void shellSort(int arr[]) {
        int d, i, j, x;
        d = arr.length / 2;
        while (d >= 1) {// 循环至增量为1时结束
            for (i = d; i < arr.length; i++) {
                x = arr[i];// 获取序列中的下一个数据
                j = i - d;// 序列中前一个数据的序列
                while (j >= 0 && arr[j] > x) {// 下一个数大于前一个数
                    arr[j + d] = arr[j];// 将后一个将向前移动
                    j = j - d;// 修改序号,继续向前比较
                }
                arr[j + d] = x;// 保存数据
            }
            d /= 2;// 缩小增量
        }
    }
}

1.4归并排序(Merge Sort)

基本思想:就是将两个或者多个有序表合并成一个有序表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

记住我的名字啊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值