排序好文章
https://www.cnblogs.com/itsharehome/p/11058010.html
一、交换排序
1、冒泡排序
这是改进的冒泡排序。主要有两点改进
(1)、外循环次数每次减一。
根据冒泡排序的性质,每一次排序都是把队列最大数的往后移,所以每完成一趟排序,后面的数据已经有序了,故,每一趟把外层循环的次数-1。当然这也影响内层循环的次数。
(2)、内层循环无移动,直接退出。
内层循环如果没有移动,说明数据已经是有序了,故而设置一个标志位默认为false,如果内层不移动,改为true,直接退出外层循环。
此算法的结果比较如下:
待排数组[4, 14, -11, 144, -15, 14, -51, 14, -1, 14, -1, 14, 1, 1]
总循环次数=70
队列长度=14
原始冒泡:
总循环次数=182
队列长度=14
几乎速度提升一倍
/*
* 冒泡排序,从头至尾遍历,每一次遍历把大的值往后移动,且每次把尾巴向前移动1
*设置一个标识位,如果内层循环没有交换说明队列已经有序,直接退出
*/
private static void insertSort(int[] a) {
int l = a.length;
int t = 0;
// 外层遍历,遍历次数i,从尾部开始的i的数不需要比较
boolean isSort = true;
for (int i = 0; i < l; i++,--l) {
// 内层遍历,从头开始遍历每次把相邻两个大的放在后面
for (int j = 0; j < l - 1; j++) {
t++;
if (a[j] > a[j + 1]) {
int swap = a[j + 1];
a[j + 1] = a[j];
a[j] = swap;
isSort = false;
}
}
// 如果内层循环没有交换说明队列已经是有序的了,就直接退出
if (isSort) {
break;
}
}
}
2、快速排序
二、选择排序
1、直接选择排序
public static void selectSort(int[] a) {
// 从头开始将组内数据作为初始最小值依次与后面数据比较
for (int i = 0; i < a.length - 1; i++) {
// 把i最为最小值下标
int min = i;
// 从i下标开始循环找最小的数的下标放入min中
for (int j = i; j < a.length; j++) {
if (a[j] < a[min]) {
min = j;
}
}
// 如果最后min中存的最小下标不是i,就把最小值赋给i下标
if (i != min) {
int swap = a[i];
a[i] = a[min];
a[min] = swap;
}
}
}
三、插入排序
1、直接插入排序
/*
* 插入排序
* 从队头到队尾依次从队列中取出一个数,把他插入左侧已经排序的队列中
* 1、从队列中取出一个数,索引为i计为a[i],存入变量t中
* 2、与i的左侧即索引从0到i-1的数依次比较
* 3、如果t比i左侧的某一个数小就把它与t交换
* 4、把通过遍历后的t存入a[i]
*/
private static void insertSort(int[] a) {
//从头开始遍历
for (int i = 0; i < a.length; i++) {
//把a[i]存入变量t中
int t = a[i];
//把上一层拿到的数字与从0到i-1依次遍历的数进行比较
for (int j = 0; j < i; j++) {
//如果t的值比a[j]小就交换他们,直至比较到i-1
if (t < a[j]) {
int z = a[j];
a[j] = a[i];
t = z;
}
//一轮比较完,t中必然存的是最大的值,把t的值赋给a[i]
a[i]=t;
}
}
}
基数排序
import java.util.Arrays;
public class myRadix {
public static void sort(int[] a) {
int bit = getBigBit(a);
//一个二位数组用于存储数据,其中第一位表示0~9的整数的基数
int[][] b = new int[10][a.length];
//n存储分位,个位1,十位2.......
int n = 1;
//p用来存储获取分位值所需要除以的数字为:0,10,100,1000
int p = 1;
//num数组用来存储0~9位上对应数的个数;使用new初始化数组为0
int[] num = new int[10];
while (n <= bit) {
for (int i = 0; i < a.length; i++) {
//dix表示个位或者十位或者百位等位上的数字(注意0%1=1)
//得到百位数字的方法是n/10 /10;先剔除个位
int dix = (a[i] / p) % 10;
//存入二位数组中,同时让num数组自增
b[dix][num[dix]++] = a[i];
}
//一次基数排序完成就把值赋给数组
//为了给原数组赋值需要记录原数组的下标,这里用t记录
int t = 0;
for (int j = 0; j < 10; j++) {
if (num[j] != 0) {
for (int k = 0; k < num[j]; k++) {
//二位数组给原数组赋值了,就把原数组的下标加1
a[t++] = b[j][k];
}
}
//一次赋值完成后,将记录个数的数组
num[j] = 0;
}
p *= 10;
n++;
}
}
//获取数组最大数位数的方法
private static int getBigBit(int[] a) {
int t = a[0];
for (int i = 0; i < a.length - 1; i++) {
if (a[i + 1] > t) {
t = a[i + 1];
}
}
//字符串转数字,根据字符串的长度确定最大数的位数
String s = String.valueOf(t);
return s.length();
}
public static void main(String[] args) {
int[] a = {7, 22, 93, 43, 55, 14, 28, 65, 39, 81, 33, 100};
sort(a);
System.out.println(Arrays.toString(a));
}
}
//基数排序,使用linkedList实现
private static void radixSort(int[] a, int l) {
int myl = 1;
int index = 1;
ArrayList<LinkedList<Integer>> s = new ArrayList<>(10);
//初始化arraylist
for (int i = 0; i < 10; i++) {
s.add(new LinkedList<>());
}
int[] n = new int[10];
while (myl <= l) {
for (int i : a) {
int t = (i / index) % 10;
s.get(t).add(i);
}
int k = 0;
for (int i = 0; i < 10; i++) {
if (!s.get(i).isEmpty()) {
for (int j : s.get(i)) {
System.out.println(j);
a[k++] = j;
}
s.get(i).clear();
}
}
myl++;
index *= 10;
}
}