冒泡排序:
1. 将要排序的元素想象成一组从上往下的泡泡,排序时,分有序和无序两个区域;
2. 开始排序的时候,有序区里只有1号泡泡,剩余泡泡在无序区;
3. 从无序区中拿出2号泡泡与有序区的1号泡泡比较,若2号小于1号则两个泡泡交换,大于则不做交换;比较后的有序区里变成两个泡泡,其余在无序区
4. 再从无序区拿出3号泡泡与有序区2号比较,小于2号则交换,交换后再与1号比较,小于1号则再交换;若与2比较时大于2号,则不做交换,本次排序完毕
5. 此时有序区变为3个泡泡,再从无序区拿出4号泡泡与有序区中3号,2号,1号比较,重复第四步操作
6. 如此循环直到无序区中的泡泡全部排序完毕
列子:数组A = {5,2,6,3}进行冒泡排序
1. 一开始有序区为[5],无序区为[2,6,3]
2. 无序区第一个元素2和有序区最后一个元素5比较,2 < 5;2和5交换,有序区变成[2,5],无序区为[6,3]
3. 无序区第一个元素6和有序区最后一个元素5比较,6 > 5;不交换,有序区变成[2,5,6],无序区为[3]
4. 无序区第一个元素3和有序区最后一个元素6比较,3 < 6;3和6交换;3再和有序区倒数第二个元素5比较,3 < 5,交换;再和下一个元素2比较
3 > 2,不交换;有序区变成[2,3,5,6],无序区为空,排序结束。
算法时间复杂度:
需要进行N-1趟排序,每趟排序需要和N-i个元素进行比较,所以时间复杂度为:O(N^2)
选择排序:
- 一开始有序区为空,无序区为整个序列,从无序区中找出最小数min1;
- 将第一个数与min交换,此时有序区变为[min1],无序区为N-1;
- 再从无序区中找到最小的数min2,将无序区第一个数(即整个序列第二个数)和min2交换;此时有序区为[min1,min2],无序区为N-2
- 重复1,2步骤直到无序区中只剩下最后一个数。
算法时间复杂度:
需要进行N-1趟排序,每趟排序需要比较N-i个元素,所以算法时间复杂度为:O(N^2)
插入排序:
- 一开始有序区中只有第一个元素,取出无序区第一个元素和无序区的元素从后向前开始比较
- 如果已排序的元素大于无序区的元素,则将已排序的元素向后移
- 如果已排序的元素小于或等于无序区元素,则停止比较。
- 重复上述步骤直到所有元素都已排序
算法时间复杂度:- 最好情况是得到的就是已经排好序的序列,该情况下只需进行N-1次比较情况
- 最差的情况是刚好是倒序,此时算法复杂度为O(N^2)
- 所以插入排序平均算法时间复杂度为:O(N^2)
源码如下:
import java.util.Arrays;
import java.util.Random;
public class ThreeKindsSort {
// 冒泡排序
public static void theBubbleSort(int[] ary) {
if (ary == null || ary.length < 2) {
return;
}
for (int i = 1; i < ary.length; i++) {
for (int j = i; j > 0; j--) {
if (ary[j] < ary[j-1]) {
exchange(ary, j, j - 1);
}
}
}
}
// 选择排序
public static void selectionSort(int[] ary) {
if (ary == null || ary.length < 2) {
return;
}
int p1 = 0;
while (p1 < ary.length - 1) {
int p2 = p1;
for (int i = p1 + 1; i < ary.length; i++) {
if (ary[p2] > ary[i]) {
p2 = i;
}
}
exchange(ary, p2, p1);
p1++;
}
}
// 插入排序
public static void insertionSort(int[] ary) {
if (ary == null || ary.length < 2) {
return;
}
for (int i = 1; i < ary.length; i++) {
for (int j = i - 1; j >= 0; j--) {
if (ary[j] > ary[j + 1]) {
exchange(ary, j, j + 1);
}
}
}
}
// 交换方法
public static void exchange(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
// 绝对正确的方法
public static int[] right(int[] ary) {
Arrays.sort(ary);
return ary;
}
// 随机产生样本器
public static int[] randomSample(int length, int numericalRange) {
Random r = new Random();
int[] arr = new int[r.nextInt(length) + 1];
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(numericalRange);
}
return arr;
}
// 备份数组
public static int[] copyArray(int[] ary) {
int[] copy = new int[ary.length];
if (ary == null) {
return null;
} else {
for (int i = 0; i < ary.length; i++) {
copy[i] = ary[i];
}
}
return copy;
}
// 比较数组
public static boolean toCompareArray(int[] arr1, int[] arr2) {
if ((arr1==null) && (arr2==null))
return true;
else if ((arr1==null) && (arr2 != null))
return false;
else if ((arr1 != null) && (arr2==null))
return false;
else {
if (arr1.length != arr2.length)
return false;
else {
for (int i = 0; i < arr1.length; i++) {
if (arr1[i] != arr2[i])
return false;
}
}
}
return true;
}
// 打印数组
public static void printArray(int[] array){
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
public static void main(String[] args) {
int length = 10;
int value = 100;
int times = 100000;
boolean result = true;
for (int i = 1; i <= times ; i++) {
int[] arr1 = randomSample(length,value);
int[] arr2 = copyArray(arr1);
// 在这里分别调用三种排序方法和类库中的方法比较
theBubbleSort(arr1);
// selectionSort(arr1);
// insertionSort(arr1);
right(arr2);
if (!toCompareArray(arr1,arr2)){
result = false;
printArray(arr1);
printArray(arr2);
break;
}
}
System.out.println(result ? "成功!" : "失败!");
}
}