交换类排序
冒泡排序
假设待排序表长为n,从后往前(或从前往后)两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。我们称它为一趟冒泡,结果将最小的元素交换到待排序列的第一个位置。下一趟冒泡时,前一趟确定的最小元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中的最小元素放到了序列的最终位置,……,这样最多做n-1趟冒泡就能把所有元素排好序。 空间复杂度:交换时开辟了存储空间来存储中间变量,所以空间复杂度为O(1) 时间复杂度 稳定性:当两个关键字相等,if判断条件不成立,所以不会发生数据移动。所以是稳定的。
void Bubble_Sort ( int * list, int count)
{
int flag = true;
int i = 0 , j = 0 ;
for ( i= 0 ; i<= count&& flag; i++ )
{
flag = false;
for ( j= count - 1 ; j>= i; j-- )
{
if ( list[ j] < list[ j- 1 ] )
{
swap ( list[ j] , list[ j- 1 ] ) ;
flag = true;
}
}
}
}
快速排序
快速排序是一种基于分治法的排序方法。 每一趟快排选择序列中任一个元素作为枢轴(pivot)(通常选第一个元素),将序列中比枢轴小的元素都移到枢轴前边,比枢轴大的元素都移到枢轴后边。 时间复杂度: 最好情况下时间复杂度为O(nlogn) ,待排序序列越无序,算法效率越高。 最坏情况下时间复杂度为O(n^2),待排序序列越有序,算法效率越低。 空间复杂度: 由于快速排序是递归的,需要借助一个递归工作栈来保存每一层递归调用的必要信息,其容量应与递归调用的最大深度一致。 最好情况下为 ⌈log2(n+1)⌉(每次partition都很均匀)递归树的深度O(logn) 最坏情况下,因为要进行n-1次递归调用,所以栈的深度为O(n); 稳定性:快速排序是不稳定的,是因为存在交换关键字。
int Partition ( int * list, int low, int high)
{
int pivotKey;
pivotKey = list[ low] ;
while ( low< high)
{
while ( low< high&& list[ high] >= pivotKey)
{
high-- ;
}
swap ( list[ low] , list[ high] ) ;
while ( low< high&& list[ low] <= pivotKey)
{
low++ ;
}
swap ( list[ low] , list[ high] ) ;
}
return low;
}
void Qsort ( int * list, int low, int high)
{
int pivot;
if ( low< high)
{
pivot = Partition ( list, low, high) ;
Qsort ( list, low, pivot- 1 ) ;
Qsort ( list, pivot+ 1 , high) ;
}
}
void Quick_Sort ( int * list, int count)
{
Qsort ( list, 0 , count- 1 ) ;
}