内排序与外排序:
内排序是在排序的过程中,待排序的所有记录均存于内存中。外排序是由于排序的记录数过多,不能同时放置于内存,整个排序过程需要在内外存之间多次交换数据才能进行。此处主要介绍内排序。
内排序性能影响的三个指标:
1 时间性能:(内排主要进行比较和移动操作)
2 辅助空间(执行算法所需的其他存储空间)
3 算法的复杂性:按照排序过程中借助的主要操作,把内排序分为(四大类:插入排序,交换排序,选择排序和归并排序),按照算法的复杂度分为两大类:简单算法和改进算法。
排序的稳定性:
在排序过程中相同元素的前后顺序并没有改变,则可认为此排序为稳定排序,反之为不稳定排序。
冒泡排序算法的实现
package simpleSorts;
public class BubbleSort {
public static void bubbleSort(int arr[]){
for(int i=0;i<arr.length-1;i++){//最多n-1趟排序
for(int j=arr.length-2;j>=i;j--){//j为从下往上比较两两相邻的元素大小,并将小的元素推上去,止于i处(i处表示前面0--i个元素已经有序)
if(arr[j]>arr[j+1]){
int temp;
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
public static void main(String[] args) {
int arr[]= {1,4,6,3,7,2,9};
System.out.println("排序前的顺序为:");
for (int i : arr) {
System.out.print(+i+" ");
}
System.out.print("\n");
bubbleSort(arr);
System.out.println("排序后的顺序为:");
for (int i : arr) {
System.out.print(+i+" ");
}
}
}
冒泡排序的原版实现(java)
冒泡排序优化版(java)
对于子序列已经有序,可以通过增加增加标识flag避免因已经有序的情况下的无意义循环判断。
package simpleSorts;
public class BubbleSort {
public static void bubbleSort1(int arr[]){
boolean flag=true;
for(int i=0;i<arr.length-1&&flag;i++){//通过增加flag标志来减少移动的趟数
flag=false;
for(int j=arr.length-2;j>=i;j--){//
if(arr[j]>arr[j+1]){
int temp;
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=true;
}
}
}
}
public static void main(String[] args) {
int arr[]= {2,1,3,5,6,7,9};
System.out.println("排序前的顺序为:");
for (int i : arr) {
System.out.print(+i+" ");
}
System.out.print("\n");
bubbleSort1(arr);
System.out.println("排序后的顺序为:");
for (int i : arr) {
System.out.print(+i+" ");
}
}
}
本例中的序列{2,1,3,5,6,7,9},第一趟过后 变为{ 1,2,3,5,6,7,9},此时的i即从数字2(也即数组下标一开始),第二趟中由于arr[j]>arr[j+1]一直不成立,所以走完这一趟后flag一直等于false,下趟再对外层for循环判断的时候一直不成立,也就减少了移动的趟数。
复杂度分析
两层for循环(外层控制躺数,内层进行两两相邻比较),O(NxN),最好的情况是表本身有序,此时就只有比较次数为N-1次,最差即为完全逆序为1/2(N)(N-1)
注:在对两数进行交换时,如果规定不能借助临时变量temp,可以采用此方法:(a^=b,b^=a,a^=b)
参考书:大话设计模式