数组常见的排序算法

android 数字大小排序 安卓数组排序_android 数字大小排序

一. Arrays.sort(数组)  (默认从小到大排序)

1.代码

public class MainActivity3 extends AppCompatActivity {

    private int[] arrays = new int[]{1, 23, 2, 32, 1, 0, 10, 100};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        for (int i : arrays) {
            Log.d("TAG", "排序前数组:" + i);
        }

        nativeMethod();
    }

    /**
     * 系统方法排序
     */

    private void nativeMethod() {
        Arrays.sort(arrays);
        for (int i : arrays) {
            Log.d("TAG", "Arrays.sort方法排序后数组:" + i);
        }
    }

}

2.结果

D/TAG: 排序前数组:1

D/TAG: 排序前数组:23

D/TAG: 排序前数组:2

D/TAG: 排序前数组:32

D/TAG: 排序前数组:1

D/TAG: 排序前数组:0

D/TAG: 排序前数组:10

D/TAG: 排序前数组:100


**********************************************************


D/TAG: Arrays.sort方法排序后数组:0

D/TAG: Arrays.sort方法排序后数组:1

D/TAG: Arrays.sort方法排序后数组:1

D/TAG: Arrays.sort方法排序后数组:2

D/TAG: Arrays.sort方法排序后数组:10

D/TAG: Arrays.sort方法排序后数组:23

D/TAG: Arrays.sort方法排序后数组:32

D/TAG: Arrays.sort方法排序后数组:100

要想获取倒序只需倒着遍历数组即可。

二.冒泡排序

1.思路

比较相邻的元素。如果第一个比第二个大,就交换他们两个。  对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。

在这一点,最后的元素应该会是最大的数。  针对所有的元素重复以上的步骤,除了最后一个。  
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 

2.代码

public class MainActivity3 extends AppCompatActivity {

    private int[] arrays = new int[]{1, 23, 2, 32, 1, 0, 10, 100};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        for (int i : arrays) {
            Log.d("TAG", "排序前数组:" + i);
        }

        nativeMethod();
    }

    /**
     * 冒泡方法排序
     */

    private void nativeMethod() {
        int count = arrays.length;
        for (int i = 0; i < count - 1; i++) {
            for (int j = i + 1; j < count; j++) {
                if (arrays[j] < arrays[i]) {
                    int temp = arrays[i];
                    arrays[i] = arrays[j];
                    arrays[j] = temp;
                }
            }
        }

        for (int i : arrays) {
            Log.d("TAG", "冒泡方法排序后数组:" + i);
        }
    }

}

3.结果

D/TAG: 排序前数组:1

D/TAG: 排序前数组:23

D/TAG: 排序前数组:2

D/TAG: 排序前数组:32

D/TAG: 排序前数组:1

D/TAG: 排序前数组:0

D/TAG: 排序前数组:10

D/TAG: 排序前数组:100


******************************************************


D/TAG: 冒泡方法排序后数组:0

D/TAG: 冒泡方法排序后数组:1

D/TAG: 冒泡方法排序后数组:1

D/TAG: 冒泡方法排序后数组:2

D/TAG: 冒泡方法排序后数组:10

D/TAG: 冒泡方法排序后数组:23

D/TAG: 冒泡方法排序后数组:32

D/TAG: 冒泡方法排序后数组:100

三.选择排序

1.思路

和冒泡差不多,也是两轮n-1,n 只不过冒泡排序比的是大小直接排序,选择排序先比较下标再交换数据

将数组的第一个数据作为最大或者最小的值,然后通过比较循环,输出有序的数组。

2.代码

public class MainActivity3 extends AppCompatActivity {

    private int[] arrays = new int[]{1, 23, 2, 32, 1, 0, 10, 100};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        for (int i : arrays) {
            Log.d("TAG", "排序前数组:" + i);
        }

        nativeMethod();
    }

    /**
     * 选择方法排序
     */

    private void nativeMethod() {
        int count = arrays.length;
        for (int i = 0; i < count - 1; i++) {
            int min = i;//认定一个最小数的位置
            for (int j = i + 1; j < count; j++) {
                if (arrays[j] < arrays[min]) {
                    min = j;
                }
            }

            if (min != i) {
                int temp = arrays[i];
                arrays[i] = arrays[min];
                arrays[min] = temp;
            }
        }

        for (int i : arrays) {
            Log.d("TAG", "选择方法排序后数组:" + i);
        }
    }

}

3.结果

D/TAG: 排序前数组:1

D/TAG: 排序前数组:23

D/TAG: 排序前数组:2

D/TAG: 排序前数组:32

D/TAG: 排序前数组:1

D/TAG: 排序前数组:0

D/TAG: 排序前数组:10

D/TAG: 排序前数组:100


***********************************************************


D/TAG: 选择方法排序后数组:0

D/TAG: 选择方法排序后数组:1

D/TAG: 选择方法排序后数组:1

D/TAG: 选择方法排序后数组:2

D/TAG: 选择方法排序后数组:10

D/TAG: 选择方法排序后数组:23

D/TAG: 选择方法排序后数组:32

D/TAG: 选择方法排序后数组:100

四.快速排序

1.思路

比如 待排序的数组:1 23 2 32 1 0 10 100。

那么我们可以找一个数作为基准线 然后经过一轮排序后做到 这个基准线的左侧的数都是比这个数小的,右侧的数都是比这个数大的。为了方便我们以最左边的数为基准线。即 基准线为1。

int j=arrays.length-1  右侧开始查找的位置。

int i=0 左侧开始查找的位置。

大致的算法描述如下:

右侧的数据只要大于等于基准线 就继续向左查找。 

左侧的数据只要小于等于基准线 就继续向右查找。  

第一轮:

j--:100(继续) 10(继续) 0(满足) j停止-- j停止的位置是右侧0的位置 下标是5。

i++:1(继续) 23(满足) i停止++ i停止的位置是左侧23的位置 下标是1。

然后交换 i和j停止位置对应的数据 即 交换 左侧23和右侧0。 交换后的数组如下

1 0 2 32 1 23 10 100
*********************************************************************************************************

第二轮:

j继续在上次停留的位置向左查找 1(继续) 32(继续) 2(继续) 但是再向左查找的话i就不小于j了(while循环中j--的条件不满足),所以j就不会继续--向左查找。

i继续在上次停留的位置向右查找 2(继续) 但是再向右查找的话i就不小于j了(while循环中i++的条件不满足),所以i就不会继续++向由查找。 

这时外部while中由于i和j大小相等 所以外部while中数组中的数据不交换 数组如下

1 0 2 32 1 23 10 100
*********************************************************************************************************

原数据:1 23 2 32 1 0 10 100
***********************************

第1轮:1 0 2 32 1 23 10 100
***********************************

第2轮:1 0 2 32 1 23 10 100
***********************************

第3轮:0 1 2 1 32 23 10 100
***********************************

第4轮:0 1 2 1 32 23 10 100
***********************************

第5轮:0 1 1 2 32 23 10 100
***********************************

第6轮:0 1 1 2 10 23 32 100
***********************************

2.代码

public class MainActivity3 extends AppCompatActivity {

    private int[] arrays = new int[]{1, 23, 2, 32, 1, 0, 10, 100};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);

        for (int i : arrays) {
            Log.d("TAG", "排序前数组:" + i);
        }

        quickSort(0, arrays.length - 1);

        for (int result : arrays) {
            Log.d("TAG", "快速排序:" + result);
        }
    }

    /**
     * 快速排序
     */

    private void quickSort(int left, int right) {
        if (left > right) return;

        //基线 即 设定一个标准 默认最左侧
        int baseLine = arrays[left];
        int i = left;//左侧游标
        int j = right;//右侧游标
        while (i != j) {
            //先看右侧
            while (arrays[j] >= baseLine && i < j) {
                j--;
            }
            //再看左侧
            while (arrays[i] <= baseLine && i < j) {
                i++;
            }

            if (i < j) {
                int temp = arrays[i];
                arrays[i] = arrays[j];
                arrays[j] = temp;
            }
        }

        //到这里i和j相等 即完成一轮工作 然后把i或者j位置对应的数据和基线交换
        arrays[left] = arrays[i];
        arrays[i] = baseLine;

        //第N轮 N-1轮找到的新基线对应的位置 左侧
        quickSort(left, i - 1);
        //第N轮 N-1轮找到的新基线对应的位置 右侧
        quickSort(i + 1, right);
    }

}

3.结果

D/TAG: 排序前数组:1

D/TAG: 排序前数组:23

D/TAG: 排序前数组:2

D/TAG: 排序前数组:32

D/TAG: 排序前数组:1

D/TAG: 排序前数组:0

D/TAG: 排序前数组:10

D/TAG: 排序前数组:100

********************************************************

D/TAG: 快速排序:0

D/TAG: 快速排序:1

D/TAG: 快速排序:1

D/TAG: 快速排序:2

D/TAG: 快速排序:10

D/TAG: 快速排序:23

D/TAG: 快速排序:32

D/TAG: 快速排序:100

五.二分查找

1.思路

二分查找是指查找数组中某个元素的位置,数组必须是排好序的。

2.代码

public class MainActivity4 extends AppCompatActivity {

    private int mArray1[] = new int[]{12, 0, 23, 111, 0, 24, 123, 89, 3, 4, 21};//11个元素
    private int mArray2[] = new int[]{12, 0, 23, 111, 24, 123, 89, 3, 4, 21};//10个元素

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);

        Arrays.sort(mArray1);//先进行排序
        Arrays.sort(mArray2);//先进行排序

        for (int i : mArray1) {
            Log.d("TAG", "mArray1排序后:" + i);
        }
        int position1 = dichotomyMethod(mArray1, 24);
        int position2 = dichotomyMethod(mArray1, 21);
        Log.d("TAG", "24在数组1中的下标:" + position1);
        Log.d("TAG", "21在数组1中的下标:" + position2);

        for (int i : mArray2) {
            Log.d("TAG", "mArray2排序后:" + i);
        }
        int position3 = dichotomyMethod(mArray2, 12);
        int position4 = dichotomyMethod(mArray2, 89);
        Log.d("TAG", "12在数组2中的下标:" + position3);
        Log.d("TAG", "89在数组2中的下标:" + position4);
    }

    /**
     * 二分法查找 数组需要提前排好序
     *
     * @param arrays 要查找的数组
     * @param num    要查找的元素
     * @return 元素在数组中的位置
     */

    private int dichotomyMethod(int[] arrays, int num) {
        if (null == arrays || arrays.length <= 0) return -1;

        int start = 0;//查找的开始位置
        int end = arrays.length;//查找的结束位置
        while (start <= end) {
            int mid = (start + end) / 2;
            if (arrays[mid] == num) {//中间位置恰好是要找的数据
                return mid;
            } else {
                //前提:数组从小到大排好序了
                if (arrays[mid] > num) {//中间的位置都比要找的数据大 则在前半部分查找 修改end值
                    end = mid - 1;
                } else {//中间的位置比要找的数据下 则在后半部分查找 修改start值
                    start = mid + 1;
                }
            }
        }
        return -1;
    }
}

3.结果

D/TAG: mArray1排序后:0

D/TAG: mArray1排序后:0

D/TAG: mArray1排序后:3

D/TAG: mArray1排序后:4

D/TAG: mArray1排序后:12

D/TAG: mArray1排序后:21

D/TAG: mArray1排序后:23

D/TAG: mArray1排序后:24

D/TAG: mArray1排序后:89

D/TAG: mArray1排序后:111

D/TAG: mArray1排序后:123


D/TAG: 24在数组1中的下标:7

D/TAG: 21在数组1中的下标:5


******************************************************************
 
D/TAG: mArray2排序后:0

D/TAG: mArray2排序后:3

D/TAG: mArray2排序后:4

D/TAG: mArray2排序后:12

D/TAG: mArray2排序后:21

D/TAG: mArray2排序后:23

D/TAG: mArray2排序后:24

D/TAG: mArray2排序后:89

D/TAG: mArray2排序后:111

D/TAG: mArray2排序后:123


D/TAG: 12在数组2中的下标:3

D/TAG: 89在数组2中的下标:7