二 交换类排序
基本思想是:两两比较待排序记录的关键字,发现两记录的次序相反时即进行交换,直到没有反序的记录为止!
1. 冒泡排序
冒泡的原则:轻气泡不能在重气泡之下!
如何进行?从下到上扫描待排记录,凡违反冒泡原则的轻气泡就向上“漂浮”。如此反复进行,直到任意两个气泡,都是轻者在上,重者在下!
void bubble_sort(int a[], int len)
{
int i, j;
for (i = 0; i < len - 1; i++) {
for (j = 1; j < len - i; j++) //这是从前向后冒,初始j = 1,以便用a[j-1].或者 (j = 0; j < len - i - 1; j++) a[j]与a[j+1]
if (a[j - 1] > a[j]) {
int tmp = a[j - 1];
a[j - 1] = a[j];
a[j] = tmp;
}
}
}
void bubble_sort(int a[], int len)
{
int i, j;
for (i = 0; i < len - 1; i++) {
for (j = len - 1; j > 0; j--) // 从后向前冒,(从下向上冒泡)
if (a[j] < a[j - 1]) {
int tmp = a[j];
a[j] = a[j - 1];
a[j - 1] = tmp;
}
}
}
注:注意下内层循环的边界问题即可
2. 快速排序
快速排序采用“分治法”,即将原问题划分为若干个规模更小,但结构与原问题相似的子问题!递归的解决这些子问题,然后将这些子问题的解组合为原问题的解!
a>划分,从待排数列中选择一个元素作为“基准zhi”,把“基准zhi”放到合适的位置,使在“基准zhi”前面的元素都比其小,在其后面的元素都比其大。基准zhi无需参加后续的排序!
b>求解,对前后子区间进行“快速排序”。
c>组合,每一次求解后都得到一个“基准zhi”,大小是按顺序来的。
具体如何划分呢?把第一个元素选作“基准zhi”。剩下的元素先于“基准zhi”相比较,并且进行移动,得到一个位置,使得在这个位置(fenjieweizhi)前的元素(基准除外),比基准小,之后的元素比基准大,然后把这个位置的元素和基准交换即可!
#define SWAP(a, b) \
do {typeof(a) tmp; tmp = (a); (a) = (b); (b) = tmp;}while(0)
void quick_sort(int data[], int left, int right)
{
int p = left;
int i;
if (left > right)
return ;
for (i = left + 1; i <= right; i++) {
if (data[i] < data[left]) {
p++;
SWAP(data[i], data[p]); // 此处改成SWAP(data[i], data[++p]),结果出错
}
}
SWAP(data[left], data[p]);
quick_sort(data, left, p - 1);
quick_sort(data, p + 1, right);
return ;
}
void quick_sorting(int a[], int len)
{
quick_sort(a, 0, len - 1);
}
注: 1.颠倒quick_sorting 和 quick_sort的顺序,会报警告warning: conflicting types for ‘quick_sort’ [enabled by default] ,(当编译器没有找到函数声明时,默认函数返回值为int)
2.快速排序经典写法(http://hi.baidu.com/gropefor/item/5d6c7312cc2022041894ecb9)
3. 快速排序的最好时间复杂度O(nlgn), 每次取的基准都相当于一个中间值,划分后基准两边元素大致相等,这样划分次数少,比较次数也少
最坏时间复杂度O(n^2), 每次划分取的基准都是无序区中最大的或最小的,划分的结果是基准的一边是空,另一边仅比划分前的无序区少一个元素!(这样要做(n-1)划分) 所以待排数列有序时,快速排序比较的次数最多
二.
void quick_sort(int a[], int left, int right)
{
int l = left, r = right;
int p = a[left];
if (l > r)
return ;
while (l < r) {
while (l < r && p <= a[r])
r--;
a[l] = a[r];
while (l < r && p >= a[l])
l++;
a[r] = a[l];
}
a[l] = p;
quick_sort(a, left, l - 1);
quick_sort(a, l + 1, right);
return ;
}
if (l > r) || if (l >= r)
return ;