算法<改进的冒泡排序、直接插入排序、折半插入排序、希尔排序、快速排序、归并排序>

1.冒泡排序

基本思想:

设待排序的序列中的元素个数为n,首先比较第N-2个元素和第N-1个元素,如果发生逆序则交换;然后对第N-3个元素和第N-2个元素做同样的处理;重复此过程直到处理完第0个元素和第一个元素。这样称为第一趟排序,第二趟排序从第N-2个元素和第N-3个元素开始做同样的操作,直到第零个元素和第一个元素。这样的排序需要N-1趟。

    public static void bubbleSort(int[] a) {
        for (int i = 1; i < a.length; i++) {
            for (int j = a.length - 1; j >= i; j--) {
                if (a[j - 1] <= a[j]) {
                    int temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;
                }
            }
        }
    }

2.改进的冒泡排序

基本思想:

如果在在冒泡排序的某一趟过程中,所有的元素都已经排序完毕,此时结束排序,就节省了冒泡排序的时间开销:

    public static void bubbleSort(int[] a) {
        boolean flag = false;
        for (int i = 1; i < a.length; i++) {
            flag = false;
            for (int j = a.length - 1; j >= i; j--) {
                if (a[j - 1] <= a[j]) {
                    int temp = a[j - 1];
                    a[j - 1] = a[j];
                    a[j] = temp;
                    flag = true;
                }
            }
            if (!flag) {
                return;
            }
        }
    }

3.直接插入排序

基本思想:

当插入第i个元素的时候,前面的V[0],V[1],…V[i-1]已经排好序。这时候用插入V[i]的关键码与已经排好序的元素的关键码进行比较,找到要插入的位置即将V[i]插入,原来的位置上的元素向后顺移。

public static void directInsertSort(int[] a) {
        int temp, j;
        for (int i = 0; i < a.length - 1; i++) {
            if (a[i + 1] > a[i]) {
                temp = a[i + 1];
                j = i;
                do {
                    a[j + 1] = a[j];
                    j--;
                } while (j >= 0 && temp > a[j]);
                a[j + 1] = temp;
            }
        }
    }

4.折半插入排序

基本思想:

设在数据表中有N个元素,第一个到第i-1个元素已经排好序了,现在要插入第i个元素,在插入的时候采用折半搜索法查找第i个元素的插入位置。

public static void binaryInsertSort(int[] a) {
        int temp, low, high, middle;

        for (int i = 0; i < a.length - 1; i++) {
            temp = a[i + 1];
            low = 0;
            high = i;
            while (low <= high) {
                middle = (high + low) / 2;
                if (temp < a[middle]) {
                    high = middle - 1;
                } else {
                    low = middle + 1;
                }
            }
            // 从要插入位置开始,向后移动数组中的元素
            for (int j = i; j >= low; j--) {
                a[j + 1] = a[j];
            }

            a[low] = temp;
        }
    }

5.希尔排序

基本思想:

设待排序的元素的个数有n个,首先取出一个gap(gap小于n)的整数,将全部元素分为gap个子序列,所有距离为gap的元素放在同一个子序列,在每一个子序列中执行直接插入排序。然后缩小gap,重复上面的子序列划分和排序工作,直到最后取出gap=1,将所有的元素放在同一个序列中排序为止。由于刚开始的时候gap的取值较大,但是子序列的元素个数少,排序速度快,到后期,gap小,元素多,但是由于前面工作的基础,大多数元素已经有序,所以排序速度仍然很快。
一般gap初始值一般取:gap=gap/3+1;
例如现在有一个序列:21 25 49 26 16 08
gap=3的时候,第一个子序列:21 26,第二个子序列:25 16 第三个子序列:49 08

public static void shellSort(int[] a) {
        int gap = a.length;
        int temp, j;
        do {
            gap = gap / 3 + 1;
            for (int i = gap; i < a.length; i++) {
                if (a[i] < a[i - gap]) {
                    temp = a[i];
                    j = i - gap;
                    do {
                        a[j + gap] = a[j];
                        j -= gap;
                    } while (j >= 0 && temp < a[j]);
                    a[j + gap] = temp;
                }
            }
        } while (gap > 1);
    }

6.快速排序

基本思想:

任取待排序序列中的某个元素作为基准(例如去第一个元素),按照元素排序码的大小,左侧序列所有元素的排序码都小于基准元素的排序码,右侧元素序列的排序码都大于等于基准元素的排序码,基准元素排在左右两个序列的中间,然后分别对两个子序列重复实施上述方法,直到所有的元素都排在相应的位置。

快速排序基准元素的选择很重要,下面是一种思路:
一个序列,10 3 50 70 6 45 59 2 28,基准元素是10,首先扫描10之后的元素如果发现比10小的元素就往10之后的位置交换 (例如这个序列中50和6交换,70和2交换,交换之后的序列变为:10 3 6 2 50 45 59 70 28),最后的时候将比基准元素小的元素的下标最大的元素和基准元素交换(10和2交换),此时返回基准元素所在的位置(10所在的下标)。

public static int anotherpartition(int[] a, int low, int high) {
        // 基准元素
        int pivot = a[low];
        // 基准元素的下标
        int location = low;

        for (int i = low + 1; i <= high; i++) {
            // 小于基准元素的交换到左侧去
            if (a[i] < pivot) {
                //先计算出基准元素左侧应该有几个位置
                location++;
                if (location != i) {
                    int temp = a[i];
                    a[i] = a[location];
                    a[location] = temp;

                }
            }

        }

        a[low] = a[location];
        a[location] = pivot;

        //返回基准元素位置
        return location;
    }
public static void quickSort(int[] a, int left, int right) {
        if (left < right) {
            int pivotpos = anotherpartition(a, left, right);
            quickSort(a, left, pivotpos - 1);
            quickSort(a, pivotpos + 1, right);
        }
    }

7.归并排序

package jdk.lang;

public class A {
    public static void main(String[] args) {

        int arra1[] = { 1, 20, 2, 6, 99, 11, 3, 66, 55, 77, 88 ,0};
        int arra2[] = new int[arra1.length];
        doSort(arra1, arra2, 0, arra1.length - 1);
        for (int i = 0; i < arra1.length; i++) {
            System.out.print(arra1[i] + "  ");
        }
    }

    public static void doSort(int arra1[], int arra2[], int left, int right) {
        if (left>=right) {
            return;
        }
        if (left < right) {
            int mid = (left + right) / 2;
            doSort(arra1, arra2, left, mid);
            doSort(arra1, arra2, mid + 1, right);
            improvedMerge(arra1, arra2, left, right, mid);
        }

    }

    private static void improvedMerge(int[] arra1, int[] arra2, int left, int right, int mid) {
        // TODO Auto-generated method stub
        int s1 = left, s2 = right, t = left, k;
        for (k = left; k <= mid; k++) {
            arra2[k] = arra1[k];
        }
        for (k = mid + 1; k <= right; k++) {
            arra2[right + mid + 1 - k] = arra1[k];
        }
        while (t <= right) {
            if (arra2[s1] <arra2[s2]) {
                arra1[t++] = arra2[s1++];
            } else {
                arra1[t++] = arra2[s2--];
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值