统一接口:
template <class T>
void sort(int lo, int hi)
{
switch (rand()%3) {
case 1:
BubbleSort(lo,hi); break;
case 2:
SelectSort(lo,hi) break;
case 3:
InsertSort(lo,hi) break;
}
}
A冒泡排序 改进版
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
改进版:
每次遍历检同时查是否有序,如果有序直接跳出循环来提高效率
typedef int Rank;
int _elem[];
bool bubble(Rank lo,Rank hi){
bool sorted = true; //标志整体有序
while(++lo < hi){
if(_elem[lo-1] > _elem[lo])
{
sorted = false;
swap(_elem[lo-1],_elem[lo]);
}
}
return sorted;
}
void BubbleSort(Rank lo,Rank hi){
while(!bubble(lo, hi--));
}
B冒泡排序 再改进
每次遍历时候记录最后一次交换的秩,可以发现在这个秩后面的元素都没有发生交换,这说明在这个秩后的元素已经满足有序的条件,可以提前跳出这次遍历。
Rank bubble(Rank lo,Rank hi){
Rank last = lo; //初始化last
while(++lo < hi){
if(_elem[lo-1] > _elem[lo])
{
last =lo;
swap(_elem[lo-1],_elem[lo]);
}
}
return last; //返回右侧逆序对的位置
}
void BubbleSort(Rank lo,Rank hi){
while(lo<(hi=bubble(lo, hi)));
}
A插入排序
它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
template<typename T>
void InsertSort(T arr[], int len) {
T temp;
for (int i = 1; i < len; i++) {
temp = arr[i];
int j;
for (j = i - 1; j >= 0 && arr[j] > temp; j--)//从temp的位置向前逐个比较,找到第一个小于等于temp的;否则就将那个数向后移动
arr[j + 1] = arr[j];
arr[j + 1] = temp; //将找到的第一个满足条件的位置后面放上temp
}
}
//这里提供另一种写法:
int a[]={4,0,2,3,1},i,j,t;
for(i=1;i<5;i++){
t=a[i];
j=i-1;
while(j>=0&&t>a[j]){
a[j+1]=a[j];
--j;
}
a[j+1]=t;
}
A选择排序
原理
首先在未排序序列中找到最小(大)元素,与起始位置交换,然后,再从剩余未排序元素中继续寻找最小(大)元素,与当前起始位置交换。以此类推。
template<typename T>
void SelectSort(T a[], int len) {
int min;
for (int i = 0; i < len - 1; i++) {
min = i;
for (int j = i + 1; j < len; j++)//从[i+i,len)区间中找到最小值
if (a[min] > a[j])
min = j;
swap(arr[i], arr[min]);//将在[i+1,len)找到的最小值于a[i]交换
}
}