1、冒泡:
当一组数要求从大到小或者从小到大排,可以用这个。
新手学习练手用
public class test {
public static void main(String[] args) {
int[] a = new int[] { 1, 3, 6, 2, 7, 9 };
array(a);
for (int s : a) {
System.out.println(s);
}
}
public static void array(int a[]) {
int temp = 0;
boolean s = true; //设置s用来判断现在数组是否已经有序,如果s变为false
//说明还是无序的,如果不变就说明数组已经有序了,就不用继续执行代码,可以节约时间
for (int i = 0; i < a.length - 1; i++) {
for (int j = 0; j < a.length - 1 - i; j++) {
//这是把数字最大的排右边,每次只把n-1-i个数字中最大的调过去
if (a[j] < a[j + 1]) {
s = false;
temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
}
}
if (s) {
break;
}
}
}
}
2、选择排序
要经历n-1次循环,时间复杂度为n*2,而且没法改进,效率低下
每次选出最小或最大的数字放在开头语或结尾。
新手学习练手用
// 选择
public static void main(String[] args) {
int[] a = new int[] { 2, 67, 8, 3, 9 };
array(a);
for (int s : a) {
System.out.println(s);
}
}
public static void array(int[] a) {
int n = a.length;
for (int i = 0; i < n - 1; i++) {
int minindex = i;
for (int j = i + 1; j < n; j++) {
if (a[j] <= a[minindex]) {
minindex = j;
}
}
int temp = a[minindex];
a[minindex] = a[i];
a[i] = temp;
}
}
3、插入排序
外部循环从第二个元素开始,因为我们将第一个元素视为已排序部分。在内部循环中,我们将要插入的元素与已排序部分的元素进行比较,如果要插入的元素小于已排序部分的元素,则将已排序部分的元素向右移动一位,以便为要插入的元素腾出空间。在内部循环结束后,我们将要插入的元素插入到正确的位置。在每次外部循环迭代后,我们可以确保前i个元素已经被排序。
小型列表上性能非常好
// 插入
public static void main(String[] args) {
int[] a = new int[] { 3, 8, 6, 935, 2, 5647, 22 };
array(a);
for (int s : a) {
System.out.println(s);
}
}
public static void array(int[] a) {
int n = a.length;
for (int i = 1; i < n; i++) {
int key = a[i];
int j = i - 1;
while (j >= 0 && a[j] > key) {
a[j + 1] = a[j];
//这里要注意,不是将j+1和j进行交换,而是直接将大的值赋值过去,
//不然永远也没法比较出来最小值,
j--;
}
a[j + 1] = key;
}
}
4、归并排序
归并排序是通过把有n个数的数组分成n部分,然后再合并,合并的时候进行排序,大的放右边小的放左边,每组排序通过对比每组最小的数,谁小谁先放,最后就可以从小到大排出来,其中利用了分治思想。
归并排序是一种分治思想的排序算法,它的基本思想是将待排序的数组分成若干个子序列,每个子序列都是有序的,然后再将子序列合并成一个有序的数组。
大型列表好用
// 归并排序
public static void main(String[] args) {
int[] a = new int[] { 2, 67, 8, 3, 9, 32, 45, 7, 22, 54 };
mergedevice(a, 0, a.length - 1);
for (int s : a) {
System.out.println(s);
}
}
//将数组分为若干子集
//递归
public static void mergedevice(int[] a, int left, int right) {
if (left == right) {
return;
}
int mid = (left + right) / 2;
mergedevice(a, left, mid);
mergedevice(a, mid + 1, right);
merge(left, mid, right, a);
}
// public static void merge(int static1, int static2, int end, int[] a) {
// int[] temp = new int[static2 - static1];
// for (int i = 0; i < static2; i++) {
// temp[i] = a[i];
// }
// int p1 = 0;
// int p2 = static2;
// for (int i = static1; i <= end; i++) {
// if (temp[p1] >= a[p2]) {
// a[i] = a[p2];
// p2++;
// if (p2 > end) {
// while (p1 < static2) {
// i++;
// a[i] = temp[p1];
// p1++;
// }
// }
// } else {
// a[i] = temp[p1];
// p1++;
// if (p1 > static2)
// break;
// }
// }
// }
//对每组进行排序
public static void merge(int left, int mid, int right, int[] a) {
int[] temp = new int[right - left + 1];
int p1 = left;
int p2 = mid + 1;
int index = 0;
while (p1 <= mid && p2 <= right) {
if (a[p1] <= a[p2]) {
temp[index++] = a[p1++];
} else {
temp[index++] = a[p2++];
}
}
while (p1 <= mid) {
temp[index++] = a[p1++];
}
while (p2 <= right) {
temp[index++] = a[p2++];
}
for (int i = left; i < right + 1; i++) {
a[i] = temp[i - left];
}
}
5、快速排序
快速排序是,先把一个数放在数组中他应该在的位置,比如2,6,3,7,1中,6应该在数组的第4个位置,也就是下标为3的位置。也就是说,让一个数的左边全都比他小,右边全都比他大。然后重复这一操作,最后所有数的左边都比他小,右边都比他大,且数组的每个数都在他应该在的位置,数组就排序好了。
大型列表好用
//快速排序
public static void main(String[] args) {
int[] a = new int[] { 2, 67, 8, 3, 9, 32, 45, 7, 22, 54 };
sss(a, 0, a.length - 1);
for (int s : a) {
System.out.println(s);
}
}
// 递归,将他循环
public static void sss(int[] array, int left, int right) {
if (left >= right) {
return;
}
int p = partition(array, left, right);
sss(array, left, p - 1);
sss(array, p + 1, right);
}
// 将一个数移动到它应该在的位置,左边的数字都比他小,右边的数字都比他大
public static int partition(int[] array, int left, int right) {
int prote = array[left];
int value = left;
int temp;
for (int i = left; i <= right; i++) {
if (array[i] < prote) {
value++;
temp = array[value];
array[value] = array[i];
array[i] = temp;
}
}
array[left] = array[value];
array[value] = prote;
return value;
}
6、堆排序
把数组堆化成大段堆或者小端堆,
public static void main(String[] args) {
int[] a = new int[] { 2, 67, 8, 3, 9, 32, 45, 7, 22, 54 };
oooa(a);
for (int s : a) {
System.out.println(s);
}
}
public static void oooa(int[] a) {
int temp;
for (int i = a.length / 2 - 1; i >= 0; i--) {
adjustHeap(a, i, a.length);
}
for (int j = a.length - 1; j >= 0; j--) {
temp = a[0];
a[0] = a[j];
a[j] = temp;
adjustHeap(a, 0, j);
}
}
public static void adjustHeap(int[] array, int i, int length) {
int temp = array[i];
for (int k = 2 * i + 1; k < length; k = 2 * k + 1) {
// 左子节点小于右子节点,k指向右子节点
if (k + 1 < length && array[k] < array[k + 1]) {
k++;
}
// 否则比较右子节点和树顶的大小(部分)
if (array[k] > temp) {
// 这里应该写成temp而不是array[i]
array[i] = array[k];
i = k;
} else {
break;
}
}
array[i] = temp;
}