冒泡、快速、选择、插入、排序

来源:互联网 发布:js array indexof ie5 编辑:程序博客网 时间:2024/06/05 11:16
package com.yyy.sortingalgorithm;import android.util.Log;/** * Created by yqr on 2016/11/3 0003. */public class AllSortAlgorithm {    /**     * 冒泡排序首先要弄清楚一共要比多少趟     * 然后弄清楚每一趟要比多少次     * 每一趟要比的次数是递减的,第一趟排序找出最大值,第二趟找出第二大。     * 65134个数字比较     * 第一趟比较3次把6放到了最后     * 第二趟比较2次把5放到倒数第二     * 第三趟比较1次确定3的位置     * 顺序就对了。     * 从上面的例子看出,n个数字要比较 n-1 (0--->numbers.length-1)     * i为趟数,每一趟比较的次数为n-1-i(0--->numbers.length-1-i)     *     * @param numbers     * @return 不需要返回值,直接影响传入的数组     */    public static void bubbleSort(int[] numbers) {        int temp = 0;        if (numbers == null || numbers.length < 1) {            return;        } else {            for (int i = 0; i < numbers.length - 1; i++) {                for (int j = 0; j < numbers.length - 1 - i; j++) {                    if (numbers[j] > numbers[j + 1]) {                        temp = numbers[j];                        numbers[j] = numbers[j + 1];                        numbers[j + 1] = temp;                    }                }            }        }    }    /**     * 找到比base大或者小的数字后,我采用的是直接交换值的办法。不需要设置中间那一下,最符合本来的意思     * 直接往两边甩的办法也是可以的。而且效率要高些     * 我写这个只是为了自己理解重新写一遍。用的话推荐quickSort1quickSort2效率低点。     * 同时要注意快排的优化(常用的是取3个数,用中间大小的数字的值作为快排中的基准base)     *     * @param numbers     * @param start     * @param end     */    public static void myQuickSort(int[] numbers, int start, int end) {        int i = start;//前面指针从传入的start开始        int j = end;//后面指针从传入的end开始        int base = numbers[end];//base去最后一个数        int temp = 0;//用于交换值        if (start > end) return;        while (i <= j) {            while (numbers[i] < base && i < j) i++;            if (i <= j) {                temp = numbers[i];                numbers[i] = numbers[j];                numbers[j] = temp;                j--;//因为这时numbers[j] = temp了。所以下面的比较比为false ->while (numbers[j] > base && i < j)                //所以这里为j--            }            while (numbers[j] > base && i < j) j--;            if (i <= j) {                temp = numbers[j];                numbers[j] = numbers[i];                numbers[i] = temp;                i++;//同理            }        }        Log.e("", "");        if (start < j)            myQuickSort(numbers, start, j);        if (end > i)            myQuickSort(numbers, i, end);        Log.e("", "");    }    static void quickSort1(int[] a, int left, int right) {        if (left >= right)/*如果左边索引大于或者等于右边的索引就代表已经整理完成一个组了*/ {            return;        }        int i = left;        int j = right;        int key = a[left];        while (i < j)                               /*控制在当组内寻找一遍*/ {            while (i < j && key <= a[j])        /*而寻找结束的条件就是,1,找到一个小于或者大于key的数(大于或小于取决于你想升        序还是降序)2,没有符合条件1的,并且ij的大小没有反转*/ {                j--;/*向前寻找*/            }            a[i] = a[j];        /*找到一个这样的数后就把它赋给前面的被拿走的i的值(如果第一次循环且key        a[left],那么就是给key*/            while (i < j && key >= a[i])        /*这是i在当组内向前寻找,同上,不过注意与key的大小关系停止循环和上面相反,        因为排序思想是把数往两边扔,所以左右两边的数大小与key的关系相反*/ {                i++;            }            a[j] = a[i];            Log.e("", "");        }        a[i] = key;/*当在当组内找完一遍以后就把中间数key回归*/        quickSort1(a, left, i - 1);/*最后用同样的方式对分出来的左边的小组进行同上的做法*/        quickSort1(a, i + 1, right);/*用同样的方式对分出来的右边的小组进行同上的做法*/                       /*当然最后可能会出现很多分左右,直到每一组的i = j 为止*/    }    /**     * 快速排序<br/>     * <ul>     * <li>从数列中挑出一个元素,称为基准</li>     * <li>重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后,     * 该基准是它的最后位置。这个称为分割(partition)操作。</li>     * <li>递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。</li>     * </ul>     *     * @param numbers     * @param start     * @param end     */    public static void quickSort2(int[] numbers, int start, int end) {        if (start < end) {            int base = numbers[start]; // 选定的基准值(第一个数值作为基准值)            int temp; // 记录临时中间值            int i = start, j = end;            do {                while ((numbers[i] < base) && (i < end))                    i++;                while ((numbers[j] > base) && (j > start))                    j--;                if (i <= j) {                    temp = numbers[i];                    numbers[i] = numbers[j];                    numbers[j] = temp;                    i++;                    j--;                }            }            while (i <= j);            if (start < j)                quickSort2(numbers, start, j);            if (end > i)                quickSort2(numbers, i, end);        }    }    /**     * 选择排序<br/>     * 1.先找到数组中最小的数字放到数组最前端,     * 2.再到该数组中找剩余的最小的数,放到第二个位置     * 3.以此类推。     * @param numbers     */    public static void selectSort(int[] numbers) {        int size = numbers.length, temp;        for (int i = 0; i < size; i++) {            int k = i;            for (int j = size - 1; j >i; j--)  {                if (numbers[j] < numbers[k])  k = j;            }            temp = numbers[i];            numbers[i] = numbers[k];            numbers[k] = temp;        }        Log.e("" , "");    }    /**     * 插入排序<br/>---(第一个数字当作已排序。从第二个数字开始取数字。)     * 取得的数字比第一个数字大,就不变。小,就交换顺序。     * 再取第三个数字一直往前面比,找到最后一个比他大的。放到他前面。     * 依次     * <ul>     * <li>从第一个元素开始,该元素可以认为已经被排序</li>     * <li>取出下一个元素,在已经排序的元素序列中从后向前扫描</li>     * <li>如果该元素(已排序)大于新元素,将该元素移到下一位置</li>     * <li>重复步骤3,直到找到已排序的元素小于或者等于新元素的位置</li>     * <li>将新元素插入到该位置中</li>     * <li>重复步骤2</li>     * </ul>     *     * @param numbers     */    public static void insertSort(int[] numbers) {        int size = numbers.length, temp, j;        for(int i=1; i<size; i++) {            temp = numbers[i];            for(j = i; j > 0 && temp < numbers[j-1]; j--)                numbers[j] = numbers[j-1];            numbers[j] = temp;        }    }}
0 0