冒泡排序:规则就是前后比较,找到最大的放在最右端,然后依次循环比较。。。。其中需要两个循环来完成该任务,外层循环标记比较的趟数,内层循环标识每一趟需要交换元素的下标。关键需要设置一个标识位,用来标识在某一趟中,是否有交换,如果没有交换,说明已经排好序了,就可以直接停止遍历循环比较了。
public class BubbleSort {
public static int[] sort(int [] array){
// 这里for循环表示总共需要比较多少轮
for (int i = 1; i <array.length ; i++) {
// 设置标记,若为true,则表示此次循环没有进行交换,也就是排序已经完成
boolean flag = true;
// 这里for循环表示每轮比较参与的元素下标
// 对当前无序的数组进行排序
// j的范围很关键,随着轮数的增加,j的范围会不断缩小
for (int j = 0; j <array.length-i ; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = false;
}
}
if(flag){
break;
}
// 第i轮的交换结果
System.out.println("第"+i+"轮排序后的结果");
display(array);
}
return array;
}
public static void display(int [] array){
for (int i = 0; i <array.length-1 ; i++) {
System.out.print(array[i]+ " ");
}
System.out.println();
}
public static void main(String[] args) {
int [] array ={2,1,4,10,12,3,5,7,6,9,8};
System.out.println("未排序的结果");
display(array);
int[] sort = sort(array);
System.out.println("排序的结果");
display( sort);
}
}
冒泡排序的时间复杂度:
最好的情况是比较一趟并没有交换,则时间复杂度为O(n);
最差时间复杂度为每一趟都需要交换,则n+n-1+.....+1=n(n-1)/2即O(n^2)
选择排序:
选择排序是每次从待排序的元素中选出最小的元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
分为三步:
1.从待排序列中,找到最小的元素
2.如果最小的元素不是待排序序列的第一个元素,将其和第一个元素交换位置
3.从余下的N-1个元素中,找出最小的元素,重复(1)、(2)步,直到排序结束。
package 数据结构;
public class ChoiceSort {
public static int [] sort(int [] array){
// 总共需要经过length-1轮的比较
for(int i =0; i<array.length-1;i++){
int min = i;
//每轮需要比较的次数
for(int j = i+1; j<array.length;j++){
if(array[min]>array[j]){
min = j;//记录目前能找到的最小值的下标
}
}
// 找到最小值和i位置所在的值进行比较,如果不同,则需要进行交换值
if(i!=min){
int temp = array[i];
array[i] = array[min];
array[min] = temp;
}
System.out.println("第"+(i+1)+"轮排序的结果");
display(array);
}
return array;
}
// 遍历数组元素
public static void display(int [] array){
for (int i = 0; i <array.length-1 ; i++) {
System.out.print(array[i]+ " ");
}
System.out.println();
}
public static void main(String[] args) {
int [] array ={2,1,4,10,12,3,5,7,6,9,8};
System.out.println("未排序的结果");
display(array);
int[] sort = sort(array);
System.out.println("排序的结果");
display( sort);
}
}
选择排序的时间复杂度与冒泡排序的时间复杂度相同。
插入排序:
直接插入排序的思想:每一步将一个待排的数据插入到前面有序序列中,直到数据插完为止。
插入排序分为直接插入排序,希尔插入排序,链表插入排序等,下面只是简单的直接插入排序。
package 数据结构;
public class InsertSort {
public static int[] sort(int [] array){
int j;
/**
* 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的
*/
for (int i = 1; i <array.length; i++) {
int temp = array[i];//记录要插入的数据
j=i;
while (j>0 && temp<array[j-1]){//从已经排好序的序列最右边开始比较,找到比其小的数
array[j]=array[j-1];//向后挪动
j--;
}
array[j] = temp;//存在比小的数插入
}
return array;
}
public static void display(int [] arr){
for (int i = 0; i <arr.length ; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int [] array ={2,1,4,10,12,3,5,7,6,9,8};
System.out.println("未排序的结果");
display(array);
int[] sort = sort(array);
System.out.println("排序的结果");
display( sort);
}
}
插入排序的性能分析:
在第一轮排序中,它最多比较一次,第二轮中,最多比较两次,依次类推,第N轮中,最多比较N-1次。因此有1+2+3+....+n-1=n*(n-1)/2
总结:上面说的三种排序,冒泡、选择、插入的时间复杂度都为O(n^2).一般不会选择冒泡排序,因为冒泡排序平均性能没有选择排序和插入排序好。其中选择排序把交换次数降为最低,但是比较次数还是挺大的。当数据量小,并且交换数据相对比较数据更加耗时的情况下,可以应用选择排序。在大多数情况下,假设数据量比较小或基本有序时,插入排序是三种算法中最好的选择。