1.冒泡排序.
每次比较相邻两个数据,如果第一个大于第二个,就交换顺序.
这样一趟下来最大的数据就在最右边.
对所有的数据进行第一趟排序后,进行了N-1次比较,进行了最少0次,最多N-1次交换
这个算法的思路是要将最小的数据项放在数组的最开始(0位置),并将最大的数据项放到最后(N-1位置).外循环的计算器out从数组的最后开始,每经过一次循环out-1,下标大于out的都是排好了,out在完成一次内部循环后就左移一位.
内层循环计数器in从数组的最开始算起,in=0,每完成一次内部循环加1,比较次数为out-1,
最多比较次数:
N-1+N-2+….+1=(N-1+1)*(N-1)*1/2=1/2N(N-1);
平均比较次数:
1/4N(N-1);
时间复杂度:O(N*N)
输出:10 11 12 18 19
不变性:out右边所有数据为有序
优化
2.选择排序
扫描所有的数据,第一次用第一个数据去和所有的数据比较,一旦发现比第一个小的,就更新第一个数据的值.每次排序下来,最小的数据都在最左边.
比较次数:
N-1+N-2+…+1 = (N-1)*N/2
交换次数:
小于N
快于冒泡排序
时间复杂度:O(N*N)
for(int i = 0; i < A.length - 1; i++) {// 做第i趟排序
int k = i;
for(int j = k + 1; j < A.length; j++){// 选最小的记录
if(A[j] < A[k]){
k = j; //记下目前找到的最小值所在的位置
}
}
//在内层循环结束,也就是找到本轮循环的最小的数以后,再进行交换
if(i != k){ //交换a[i]和a[k]
int temp = A[i];
A[i] = A[k];
A[k] = temp;
}
}
不变性:下标小于或等于out 的数据为有序
3.插入排序
有一个已经有序的数据序列,要求在这个已经排好的数据序列中插入一个数,但要求插入后此数据序列仍然有序,这个时候就要用到一种新的排序方法——插入排序法,插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的、个数加一的有序数据
最多需要的比较和复制次数:
N-1+N-2+…+1=N(N-1)/2
平均:N(N-1)/4
但是一次复制和交换的顺序不同,随机数据的情况下,插入比冒泡快一倍,比选择略快
不变性:局部有序