选择排序:
for(int i = 0 ; i < n ; i ++){
// 寻找[i, n)区间里的最小值
int minIndex = i; //记录在区间[i,n)区间内最小值的下标
for( int j = i + 1 ; j < n ; j ++ )
if( arr[j] < arr[minIndex] )
minIndex = j;
swap( arr[i] , arr[minIndex] ); //系统内置函数,c++版本不同,有的需要引用<algorithm>
}
选择排序对待排序的数组无具体要求,几乎排序完成所用的时间都是一样的。选择排序的缺点是它每一次找出一个元素的正确位置时,都要向后遍历到数组结束才能得出结论,因此很费时间。
插入排序:
for( int i = 1 ; i < n ; i ++ )
{
for( int j = i ; j > 0 ; j-- )
if( arr[j] < arr[j-1] )
swap( arr[j] , arr[j-1] );
else
break; //插入排序是可以提前结束循环的
}
如果用上面的插入排序代码和选择排序比的的话,发现排一个相同的数组,插入排序用的时间反而更多,明明插入排序可以提前结束循环的,不需要像选择排序那样每次都必须从i+1循环到数组的末尾,但时间用的却更多了。这个主要是因为在插入排序中用到了很多次的交换操作,时间花到了这里。
插入排序(改):
void insertionSort(T arr[], int n){ (默认从小到大排序)
for( int i = 1 ; i < n ; i ++ )
{
T e = arr[i]; //每次先赋值一个副本
int j; // j保存元素e应该插入的位置
for (j = i; j > 0 && arr[j-1] > e; j--) //如果前一个元素比后一个元素大
{
arr[j] = arr[j-1]; //把前一个往后移
}
arr[j]=e //当前面arr[j-1]的小于e时就可以把它放在下标为j的位置了
}
1.插入排序的实现每次只要考虑前一个元素与本身的大小关系是否满足排序的要求(从小到大?从大到小)若满足则就找到了合适的插入位置。
2.这样改过后的插入排序算法就比选择排序快了,并且在数组基本有序的情况下其速度接近甚至超过nlgn型算法,在实际应用中很常用。
3.选择排序的内循环是从当前位置向末尾循环,选择出这段区间里的最小值与当前位置的元素交换,而插入排序的内循环是从当前的位置向开头循环找到合适的插入位置。