分治法

二分查找

在android的SparseArray中get方法就是通过二分法查找到结果。
二分查找的前提是有一个已经排好序的数组。


二分查找

思路:假设我们需要查找22这个值在数组中的位置,如上图的数组,取数组的中间下标5中的值,为21,用目标值22跟21做对比,22大于21,就在右边继续查找22这个值,否则在左边查找。
接着再从剩下的数组大小中同理取一半的下标为8,值是62同目标22对比大于22,这在右边查找。以此类推,直到找到目标22为止,返回22的下标。没找到返回负 1。

 public void Test(){
        int[] array = {4,7,8,10,14,21,22,36,62,77,81,91};
        int key = 22;
        System.out.println(binarySearch(array,0,array.length,key));
    }
/**
     * 在array中从start到end查找有没有key这个值
     * @param array
     * @param start
     * @param end
     * @param key
     */
    private int binarySearch(int[] array,int start,int end,int key){
        int lo = 0;
        int low = start;
        int hight = end -1;

        while (low < hight){
            int mid = (low + hight)>>>1;
            int midVal = array[mid];
            if (midVal <key){
                low = mid +1;
            }else if (midVal > key){
                hight = mid -1;
            }else {
                return mid;
            }

        }
        return ~lo;
    }

输出结果就是 6

也有使用递归的思想去实现二分查找,但不建议这样做。

 /**
     *  递归实现二分查找
     * @param array
     * @param start
     * @param end
     * @param key
     * @return
     */
    private int binarySearch2(int[] array,int start,int end,int key){
        int mid = (start+end)>>>1;
        if (array[mid] == key){
            return mid;
        }
        if (start <end){
            if (array[mid] < key){
                return binarySearch2(array,mid + 1,end,key);
            }else if (array[mid] > key){
                return binarySearch2(array,start,mid - 1,key);
            }
        }
        return 0;
    }

快速排序
应用场景:大量数据并且是线性结构。
短处:
1、有大量重复数据,性能不好。
2、单向链式结构处理性能不好(一般来说,链式都不使用)

排序排序的思想:

给一组数据进行排序,首先把左边第一个值暂存在T上。


在数组两端各定义一个指针(就叫指针吧,好理解)。


移动high指针取值,然后跟T中存的数据比对(这里是31)。


如果high指针取的值(12)比暂存的值(31)小。


就替换low指针指向的值。


接着换low指针移动跟暂存的值(31)做对比。



如果low指向的值(68)比暂存值(31)大。



就把high指向的值替换为low的值。

接着再次更换移动的指针为high。

同样的指针指向的值(23)比暂存值(31)小,就替换。



用high指针的值替换low指针的值。

同理,再次切换指针移动,比暂存值大就往high指针替换,比暂存值小就往low指针替换。

最后两个指针指到了同一个值上。

把暂存值替换上去。

这样第一轮的排序完成,31左边的都比它小,右边的都比它大。
然后排序左边和右边,实现整个数组的排序。

  public void testQuickSort(){
        int[] array = new int[]{31,68,45,90,23,39,54,12,87,76};
        quickSort(array,0,array.length-1);
        for (int i = 0;i<array.length;i++){
            System.out.print(array[i]+" ");
        }
    }
 private void quickSort(int[] array,int begin,int end){
        if ((end - begin)<=0) return;
        int x = array[begin];
        int low = begin;
        int high = end;
        //由于会从两个方向取数据,需要定义一个方向;
        boolean direction = true;
        //开始排序
        L1:
        while (low < high){
            if (direction){
                //从右到左的找
                for (int i = high;i>low;i--){
                    if (array[i]<=x){
                        array[low++] = array[i];
                        high = i;
                        direction = !direction;
                        continue L1;
                    }
                }
                high = low;
            }else {

                for (int i= low;i<high;i++){
                    if (array[i]>=x){
                        array[high--] = array[i];
                        low = i;
                        direction = !direction;
                        continue L1;
                    }
                }
                low = high;
            }
        }
        //把最后找到的值放入中间位置
        array[low] = x;
        //开始完成左右两边的操作
        quickSort(array,begin,low-1);
        quickSort(array,low+1,end);

    }

归并排序
思想:


应用场景:数据量大并且是链式结构。
短处:需要空间大。

 public static void mergeSort(int[] array, int left, int right) {
        if (left == right) {
            return;
        } else {
            int mid = (left + right) >>> 1;
            mergeSort(array, left, mid);//排好左边  L
            mergeSort(array, mid + 1, right);//排好右边  R
            merge(array, left, mid + 1, right);//再对左右进行合并 D
        }
    }
//归并排序
    public static void merge(int[] array, int left, int mid, int right) {
        int leftSize = mid - left;
        int rightSize = right - mid + 1;
        //生成数组
        int[] leftArray = new int[leftSize];
        int[] rightArray = new int[rightSize];
        //填充数据
        for (int i = left; i < mid; i++) {
            leftArray[i - left] = array[i];
        }
        for (int i = mid; i <= right; i++) {
            rightArray[i - mid] = array[i];
        }
        //合并数组
        int i = 0;
        int j = 0;
        int k = left;
        while (i < leftSize && j < rightSize) {
            if (leftArray[i] < rightArray[j]) {
                array[k++] = leftArray[i++];
            } else {
                array[k++] = rightArray[j++];
            }
        }
        while (i < leftSize) {
            //左边还有数据没用完
            array[k++] = leftArray[i++];
        }
        while (j < rightSize) {
            //右边还有数据没用完
            System.out.print("k:" + k);
            System.out.print("length:" + array.length);
            array[k++] = rightArray[j++];
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • 1.查找技术 1)顺序表查找,一个一个的遍历下去比对查找就ok了。 2)可以使用哈希表查找。 3)二分法查找,每次...
    仲达_dc6c阅读 260评论 0 0
  • 分治法是一种把大问题分解为小问题逐个求解,再把结果合并的解决方案,分治法衍生出的算法包含二分查找、合并排序、快速排...
    怀念小兔阅读 325评论 0 0
  • 原创-转载请注明出处。 分治法 分治法是一种很重要的算法,也就是“分而治之”的意思,就是把一个复杂的问题分解成两个...
    程序猿Jeffrey阅读 4,111评论 0 1
  • 分治法是一种算法思想,顾名思义就是分而治之的意思。把一个很难解决的问题划分成许多小问题进行解决然后合并。在计算机算...
    LikeWhoWho阅读 771评论 0 0
  • 我们的
    柠檬夏天的c阅读 128评论 0 0