常见排序笔记

排序

//工具类

package shujujiegou.sort;

 

import java.util.Random;

 

public class methodClass {

//输出排序前和排序后的数组,并加以分离

    

    public static void print(int a[],Sort sort){

        System.out.print("排序前 :");

        print(a);

        sort.Sort(a);

        System.out.println();

        System.out.print("排序后 :");

        print(a);

        System.out.println();

        

    }

    //格式化输出

    public static void print(int a[]){

        for (int i = 0; i < a.length; i++) {

         System.out.format("%3d", a[i]);

            

        }

        

    }

    // 自动生成数组方法

    public static int[] random(int i) {

        Random ra = new Random();

        int a[] = new int[i];

        for (int j = 0; j < a.length; j++) {

            a[j] = ra.nextInt(100); //100以内的数

 

        }

        return a;

    }

 

}

package shujujiegou.sort;

 

//基类

public abstract class Sort {

public abstract void Sort(int a[]);

 

//制定随机数组多少个元素

void Sort(int num) {

     System.out.println("************"+this.getClass().getSimpleName()+"************");

    methodClass.print(methodClass.random(num), this);

    

}

//默认10个元素

public void Sort() {

     System.out.println("************"+this.getClass().getSimpleName()+"************");

    ;

    methodClass.print( methodClass.random(10), this);

    

}

//制定排序数组

public void sortWithArray(int a[]) {

     System.out.println("************"+this.getClass().getSimpleName()+"************");

    methodClass.print(a, this);

    

}

}

 

直接插入排序

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

 

 

public class insertSort extends Sort{

 

 

    

    @Override    

    public void Sort(int[] a) {

          

        

        /*

         * 基本思想 对前23456n-1 个数分别进行排序

         *          排序一趟,前n-1个就已经排序好,只需找到要将第N个数插入的位置

         * 对于一个数组 a[]={a1,a2,a3,a4,a5,a6,a7,a8,a9};

         *          a[]={ 9, 8, 7, 6, 5, 4, 3, 2, 1};

         * 我们进行a.length-1次排序

         * 先把第一个元素当做是已排序的,

         * 再排序前两元素

         * 然后前三个

         *

         * 例如第3个元素

         * 假设数组为 231

         * 进行这样的交换

         * 如果3>1 1=3

         * 如果 2>1 3=2

         * 最后 2=1

         * 也就是说让

         * a[i+1]=a[i]

         *

         * 保证两点:

         * 1、取一个关键元素

         * 2、找到他所插入的位置

         */

 

        for (int i = 1; i < a.length; i++) {//外层n-1

            int temp = a[i], j;//存储要插入的数的值和下标

            for (j = i - 1; j >= 0 && temp < a[j]; j--) {

                a[j + 1] = a[j];

            }//这个for循环是找到 插入的数的位置

            a[j + 1] = temp;

            /*

             * System.out.println("" + i + ""); print(table);

             * System.out.println();

             */

        }

    }

 

      

    

 

}

 

希尔(缩小量)排序(Shell's Sort)

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

 

public class shellSort extends Sort {

 

    @Override

    /*

     * 希尔排序,缩小量排序 (non-Javadoc)

     *

     * 此时会分元组个数为奇数还是偶数,

     * 偶数 平均两两配对

     * 例如 a1 a2 a3 a4 a5 a6

     * a1 a4

     * a2 a5

     * a3 a6

     * 这样正好3对,j-=delta 不会多出

     * 而如果是奇数

     * 例如 a1 a2 a3 a4 a5

     * a1 a3

     * a2 a4

     * a3 a5

     * a1 a3

     * 这里指的都是下标 就会分成四对

     *

     * 而且当第二次分组后 ,并不是一组一组来进行直接排序的

     * 而是这样

     * 例如 a1 a2 a3 a4 a5 a6 a7 a8

     * 分组为 a1 a3 a5 a7

     * a2 a4 a6 a8

     * 此时最内层排序时

     * 是先选择 a1 a3 a5 a7 这一组的 a1 a3

     * 然后排序 a2 a4 a6 a8 这一组的a2 a8

     * 再进行 a1 a3 a5 的排序

     * 然后 a2 a4 a6的排序

     *

     * 不是一组一组来的, 这和定义有很大出入 (不过透明上看做是 一组一组来的)

     * 但还是有分组的思想在里面的

     *

     *

     * @see shujujiegou.sort.Sort#Sort(int[])

     */

    public void Sort(int[] table) {

 

        for (int delta = table.length / 2; delta > 0; delta /= 2) {

            for (int i = delta; i < table.length; i++) {

 

                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;

 

            }

            System.out.println("外层");

        }

    }

 

}

 

因为是交换的排序,分了组,所以肯定不稳定

冒泡排序

 

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

 

public class bubbleSort extends Sort {

 

    @Override

    public void Sort(int[] table) {

        // TODO Auto-generated method stub

        boolean exchange = true;

        /*

         * 这个算法是从看元素的大小位置,如果不符合策略,就交换位置

         * 而对外表现为 一次排序 一个元素到达了合适位置

         * 因此如果有元素没有发生交换就 可以停止交换了

         *

         * 它的核心思想是,查看相邻元素大小,不符合策略,交换

         * 因为是 相邻交换,所以它也是稳定的,不会打乱元素的相对位置

         */

      

        for (int i = 1; i < table.length && exchange; i++) {

            exchange = false;

            int temp ;

            for (int j = 0; j < table.length - i; j++) {

                if (table[j] > table[j + 1]) {

                    exchange = true;

                    temp    = table[j];

                    table[j] = table[j + 1];

                    table[j + 1] = temp;

                }

            }

        }

    }

    /*

     * 这也算是一种冒泡排序

     * 有直接插入排序和冒泡的思想

     *

     * 利用直接插入排序的 分别排序 N个元素, 使子序列一直是排序的

     * 而未排序的下一个元素 则按照真正的冒泡来 选择到合适的位置,

     *

     * a1 a2 a3 a4 a5

     * a1 有序

     * a2 冒泡

     * a1 a2 有序

     *         a3冒泡

     * a1 a2 a3 有序

     *             a4冒泡

     */

    

    public void Sort2(int[] a ) {

        

         for (int i = 1; i < a.length; i++) {

        

             for (int j = i-1; j>=0&&a[j+1]<a[j]; j--) {

            

                int temp=a[j+1];

                    a[j+1]=a[j];

                    a[j]=temp;

                

                

            }

        }

    }

 

}

 

快速排序

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

 

public class quickSort extends Sort {

 

    @Override

    /*

     * 选一个关键字 数组元素中<它扔前面,>它扔后面

     * 然后再在这两个子序列中选择关键字 ,重复上述操作

     * (non-Javadoc)

     * @see shujujiegou.sort.Sort#Sort(int[])

     */

    public void Sort(int[] a) {

        Sort(a, 0, a.length-1);

        

    }

    //重载方法, 为了使用递归,和让用户直接使用带一个数组参数的快速排序方法

    public void Sort(int a[],int begin,int end){

        if(begin<end){ //验证合法

            int i=begin,j=end,vot=a[i];// i j vot 存储值 而且将数组的第一个元素作为基准

            while(i!=j){//ij不相等时证明 元素未移动完成

             //先找小的元素

                while(i<j&&a[j]>=vot){ //从后往前找, 如果最后一个元素是大于基准的,不用动,让j--,找下一个,直到a[j]<=vot为止

                    j--;

                }

                //找到小的元素了, 开始移动 ,往空的下标填

                //空的下标当然要往i可能的范围填, 开始当然是第一个元素,然后将i+1,将空位移到下一个元素

                if(i<j){

                    a[i++]=a[j]; //这里是i++, i是后加的 ,要让找出来的小于关键字的a[j] 去占空位

                }

                // 找大的元素

                while(i<j&&a[j]<=vot){ //从前往后找, 如果第一个元素是小于基准的,不用动,让i++,找下一个,直到a[j]>=vot为止

                    i++;

                }

                //找到小的元素了, 开始移动 ,往空的下标填

                //空的下标当然要往j可能的范围填,刚开始当然是移动到前面的空的j了,然后将j移到下一个空的

                if(i<j){

                    a[j--]=a[i]; //这里是j--, j是后减的,要让找出来的大于关键字的 a[i]去占空位

                }

            }

            

            a[i]=vot; // 基准值到达最后位置 也可以写成 a[j]=vot

             //递归调用

            Sort(a, begin, j-1); //前端排序,

            Sort(a,i+1, end);//后端排序

        }    

    }

 

    /*

     *

     *

     *

     * 因为它随意的交换的元素之间的关系, 所以是不稳等的

     */

}

 

 

选择排序

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

 

public class selectSort extends Sort {

 

    @Override

    /*

     * 基本思想: 选择数组中最小的 放在第1位, 然后再选 放在第2 这样前N个始终是排序好的 (non-Javadoc)

     * 只有一点可以值得说说

     *

     * 就是求最大值下标和求最大值

     * 最大值下标核心

     * if(a[j]<a[min]){

                    min=j;

                }

        

     *最大值核心

     *if(max<a[j]){

     *max=a[j];

     *}

     *

     *还不如求到下标后 return array[min]

     * 也是不稳定的

     * @see shujujiegou.sort.Sort#Sort(int[])

     */

    public void Sort(int[] a) {

        for (int i = 0; i < a.length - 1; i++) {

 

            int min = i;

            for (int j = i + 1; j < a.length; j++) {

                if(a[j]<a[min]){

                    min=j;

                }

            }

             int temp=a[min];

             a[min]=a[i];

             a[i]=temp;

        }

    }

}

 

 

归并排序

感觉好难的额,

package shujujiegou.sort.method;

 

import shujujiegou.sort.Sort;

import shujujiegou.sort.main;

 

public class mergeSort extends Sort {

    /*

     * 我还是感觉比较难得 一个方法理解了好长时间, 其原理就是将两个已经排序的子数组归并成一个 再往下细分, 就是将一个数组 分为两个元素一组,

     * 然后进行归并 核心方法是 merge() 归并方法 (non-Javadoc)

     *

     *

     * 这个算法好难, 他以空间换时间了,

     * 是稳定的

     * @see shujujiegou.sort.Sort#Sort(int[])

     */

    @Override

    public void Sort(int[] a) {

        mergeSort(a);

 

    }

 

    /*

     * 核心方法merge 原理是这样 m r-1 r r+n-1 X数组为 5 7 9 11 12 1 3 10 15 i j Y数组为 1 3 5 7

     * 9 10 11 12 15 为辅助数组 k 5 1比较1Y中,j++,K++,i不变 5 3比较3Y中,j++,k++,i不变 5

     * 10比较5Y中,i++,k++,j不变 这样下去直到 两个子序列 其中一个到达尾部 再将剩下的归并到Y中就可以了

     */

    private void merge(int X[], int Y[], int m, int r, int n) {

        int i = m, j = r, k = m;

        while (i < r && j < r + n && j < X.length) { // X中的两个相邻子序列归并到Y

            if (X[i] < X[j]) {// 选择较小的值

                Y[k++] = X[i++];

            } else {

                Y[k++] = X[j++]; // 看不懂看上面

            }

        }

 

        // 将前一个子序列剩余元素复制到Y

        while (i < r) {

            Y[k++] = X[i++];

        }

        while (j < r + n && j < X.length) {

            Y[k++] = X[j++];

        }

    }

 

    private void mergePass(int X[], int Y[], int n) {

        int i = 0;

        while (i < X.length - 2 * n + 1) { // 不明白 ,为什么不可以写成 i<X.length/2

            merge(X, Y, i, i + n, n); // 一个一个归并 a1 a2 a3 a4 a5 a6 a7

                                        // a1 a2 归并 a3 a4归并 a5 a6 归并 a7先留下来

            i += 2 * n;

        }

        if (i + n < X.length) {

            merge(X, Y, i, i + n, n); // 还有可以配对的两个元素,再一次归并排序

        } else {

            for (int j = i; j < X.length; j++) { // X的剩余元素复制到Y

                Y[j] = X[j];

            }

        }

    }

 

    // 归并总排序

    private void mergeSort(int X[]) {

 

        int[] Y = new int[X.length];

        int n = 1;

        while (n < X.length) {

            mergePass(X, Y, n);

            n *= 2; // 2个归并 4 个归并 ---------------

            if (n < X.length) {

                mergePass(Y, X, n); // Y再归并至X

            }

        }

 

    }

 

}

 

 

 

名称

复杂度

说明

备注

冒泡排序
Bubble Sort

O(N*N)

将待排序的元素看作是竖着排列的"气泡",较小的元素比较轻,从而要往上浮

  

插入排序

Insertion sort

O(N*N)

逐一取出元素,在已经排序的元素序列中从后向前扫描,放到适当的位置

起初,已经排序的元素序列为空

选择排序

O(N*N)

首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此递归。

  

快速排序

Quick Sort

O(n *log2(n))

先选择中间值,然后把比它小的放在左边,大的放在右边(具体的实现是从两边找,找到一对后交换)。然后对两边分别使用这个过程(递归)。

  

堆排序HeapSort

O(n *log2(n))

利用堆(heaps)这种数据结构来构造的一种排序算法。堆是一个近似完全二叉树结构,并同时满足堆属性:即子节点的键值或索引总是小于(或者大于)它的父节点。

近似完全二叉树

希尔排序

SHELL

O(n1+)

0<<1

选择一个步长(Step) ,然后按间隔为步长的单元进行排序.递归,步长逐渐变小,直至为1.

  

箱排序
Bin Sort

O(n)

设置若干个箱子,把关键字等于 k 的记录全都装入到第个箱子里 ( 分配 ) ,然后按序号依次将各非空的箱子首尾连接起来 ( 收集 ) 

分配排序的一种:通过分配 "  " 收集 " 过程来实现排序。

桶排序

Bucket Sort

O(n)

桶排序的思想是把 [0  1) 划分为 n 个大小相同的子区间,每一子区间是一个桶。

 

 

 

排序法

 平均时间

最差情形

稳定度

额外空间

备注

冒泡

 O(n2)

  O(n2)

 稳定

O(1)

n小时较好

交换

  O(n2)

  O(n2)

不稳定

O(1)

n小时较好

选择

 O(n2)

 O(n2)

不稳定

O(1)

n小时较好

插入

 O(n2)

 O(n2)

稳定

O(1)

大部分已排序时较好

基数

O(logRB)

O(logRB)

稳定

O(n)

B是真数(0-9)R是基数(个十百)

Shell

O(nlogn)

O(ns) 1<s<2

不稳定

O(1)

s是所选分组

快速

O(nlogn)

O(n2)

不稳定

O(nlogn)

n大时较好

归并

O(nlogn)

O(nlogn)

稳定

O(1)

n大时较好

O(nlogn)

O(nlogn)

不稳定

O(1)

n大时较好

 

 

http://blog.csdn.net/iamfranter/article/details/6825207

明天看 来完善自己的博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值