常见排序

 排序算法的根本目的就是最大可能,减少比较次数来排序。如冒泡。浪费了很多次比较的结果。所以出现快排。只是调整下位置。下次排序就只要排2部分的其中一部分。

最优和稳定的解当然是每次比较,就稳定少一半。所以所有的排序目的就是如何每次都稳定的求出一半大,一半小。

有空加上堆排:1.先建立大堆,往上冒泡,下来的泡再一直往下。  2,2选1,后插。

排序可以复习下。本身代码简洁。

//常见的排序,冒泡,归并,快排。
    public static class sort
    {
        public static int[] getData()
        {
            int[] ret=new int[]{5,2,9,-3};
            return ret;
        }
        
        //冒泡,浪费了很多次比较,每次循环,没有为下一次循环提供帮助。时间复杂度 n平方
        public static void popo()
        {
            int[] data=getData();
            int tempMax=0;
            for(int i=0;i<data.length;i++)
            {
                int tempIndex=i;
                for(int h=i+1;h<data.length;h++)
                {
                    if(data[h]>data[tempIndex])
                    {
                        tempIndex=h;
                    }
                }
                tempMax=data[tempIndex];
                data[tempIndex]= data[i];
                data[i]=tempMax;
            }
            printLog(data);
        }
        
        public static void printLog(int[] ret)
        {
            for(int i=0;i<ret.length;i++)
            {
                LSLog.printLine(ret[i]+"", 1);
            }
        }
        
        //归并排序, 典型的分治:问题太大。那么就把问题一拆为二,结果分别排序好的组合起来,当为1时,不需要拆和排序。是最小问题。
        public static void merginSort()
        {
            int[] data=getData();
            if(data.length>=2)
            {
                mergin(data, 0, data.length-1);
            }
            printLog(data);
        }
        
        //分解:中分from to.合并2个。  最小问题:1个数字。不用处理。
        private static void mergin(int[] data,int from,int to)
        {
            int lengto=to-from+1;
            int half=lengto/2;
            LSLog.printLine("from:"+from+".to:"+to+".half:"+half, 1);
            assert(half>=0):"???";
            if(lengto==1)
            {
                
            }
            else
            {
                mergin(data, from, from+half-1);
                mergin(data, from+half, to);
                int dynamicFrom=from;
                for(int i=half;i<=to;i++)
                {
                    for(int h=dynamicFrom;h<=half-1+i-half;h++)
                    {
                        if(data[i]<data[h])
                        {
                            int tempMin=data[i];
                            System.arraycopy(data, h, data, h+1,i-h);
                            data[h]=tempMin;
                            dynamicFrom=h+1;
                        }
                    }
                }
            }
        }


归并排序和递归逻辑总结

分2组,一直分,直到只有一个元素。 再排2个组的序
规模最小是单个元素,比作是从小到大有序的,每次都从小到大排序,来组合2个。
那么之后2个组都是已经是从小到大,所以排序逻辑就简单了


递归函数
1.退出机制:单个元素。
2.缩小规模并解决:平分2组。递归后,再排序。

 



快排。
//冒泡实在不行,浪费了很多次比较结果。
//快排,找一个基准,左小右大。再递归这2个数组,同样的左小右大。

唯一避免每次都没分到组。


[5, 2, 9, 1, 5, 6, 7];


基准最小,或者最大, 起码基准要分出去。


小数区域索引为-1,,
对比基准,小于等于基准, 小区索引+1, 不动(i=小区索引)
大于基准 小区索引不变 不动。
小于等于基准, 小区索引+1, 交换(i 不等于索引)

考虑极端 1.基准最大或者最小, 因为条件是小于等于。所以索引一定会动。
2.空数组会提前出去。所以索引初始为-1 ,没有问题。


递归函数
1.退出机制:单个元素。
2.缩小规模并解决:取基准值,分2组左小右大排序,2组递归


 

posted @ 2016-11-05 10:18  琴鸟  阅读(245)  评论(0)    收藏  举报