1.基本思想:冒泡排序将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为ki的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R;凡扫描到违反本原则的轻气泡,就使其向上"漂浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。
冒泡排序的具体过程如下:
第一步,先比较k1和k2,若k1>k2,则交换k1和k2所在的记录,否则不交换。继续对k2和k3重复上述过程,直到处理完kn-1和kn。这时最大的排序码记录转到了最后位置,称第1次起泡,共执行n-1次比较。与第一步类似,从k1和k2开始比较,到kn-2和kn-1为止,共执行n-2次比较。
依次类推,共做n-1次起泡,完成整个排序过程。
2.时间复杂度
若文件的初始状态是正序的,一趟扫描即可完成排序。所需关键字比较次数为n-1次,记录移动次数为0。因此,冒泡排序最好的时间复杂度为O(n)。
若初始文件是反序的,需要进行n-1趟排序。每趟排序要进行n-i次关键字的比较(1<=i<=n-1),且每次比较都必须移动记录三次来达到交换记录位置。在这种情况下,比较次数达到最大值n(n-1)/2=O(n^2),移动次数也达到最大值3n(n-1)/2=O(n^2)。因此,冒泡排序的最坏时间复杂度为O(n^2)。
3.稳定性
虽然冒泡排序不一定要进行n-1趟,但由于它的记录移动次数较多,故平均性能比直接插入排序要差得多。冒泡排序是就地排序,且它是稳定的。
4.代码
void bubble_sort(int a[], int n)
{
int i = 0;
int j = 0;
int swap;
int flag = 0;
for ( i=0; i<n-1; i++)
{
flag = 0;
for ( j=0; j<n-i-1; j++)
{
if ( a[j+1]<a[j] )
{
swap = a[j+1];
a[j+1] = a[j];
a[j] = swap;
flag = 1;
}
}
if ( 0 == flag )
{
break;
}
}
}
二、直接选择排序(选择排序)
1、思想:首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。具体做法是:选择最小的元素与未排序部分的首部交换,使得序列的前面为有序。
2、时间复杂度
最好情况下:交换0次,但是每次都要找到最小的元素,因此大约必须遍历N*N次,因此为O(N*N)。减少了交换次数!
最坏情况下,平均情况下:O(N*N)
3、稳定性
由于每次都是选取未排序序列A中的最小元素x与A中的第一个元素交换,因此跨距离了,很可能破坏了元素间的相对位置,因此选择排序是不稳定的!
4、代码
void dir_sort(int a[], int n)
{
int i = 0;
int j = 0;
int k = 0;
int temp = 0;
for ( i=0; i<n-1; i++)
{
k = i;
for ( j=i+1; j<n; j++)
{
if ( a[j] < a[k] )
{
k = j;
}
}
if ( k != i )
{
temp = a[k];
a[k] = a[i];
a[i] = temp;
}
}
}
三、快速排序(交换排序)
1、思想:它是由冒泡排序改进而来的。在待排序的n个记录中任取一个记录(通常取第一个记录),把该记录放入适当位置后,数据序列被此记录划分成两部分。所有关键字比该记录关键字小的记录放置在前一部分,所有比它大的记录放置在后一部分,并把该记录排在这两部分的中间(称为该记录归位),这个过程称作一趟快速排序。
2、算法复杂度
最好的情况下:因为每次都将序列分为两个部分(一般二分都复杂度都和logN相关),故为 O(N*logN)
最坏的情况下:基本有序时,退化为冒泡排序,几乎要比较N*N次,故为O(N*N)
3、稳定性
由于每次都需要和中轴元素交换,因此原来的顺序就可能被打乱。如序列为 5 3 3 4 3 8 9 10 11会将3的顺序打乱。所以说,快速排序是不稳定的!
4、代码
#include <stdio.h>#include <stdlib.h>
void print(int a[], int n)
{
int j = 0;
for ( j=0; j<n; j++)
{
printf ("%d ", a[j]);
}
printf ("\n");
}
void swap(int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition(int a[], int low, int high)
{
int privotkey = a[low];
while ( low < high )
{
while ( low<high && a[high]>=privotkey )
{
--high;
}
swap(&a[low], &a[high]);
while ( low<high && a[low]<=privotkey )
{
++low;
}
swap(&a[low], &a[high]);
}
//print(a, 10);
return low;
}
void quick_sort(int a[], int low, int high)
{
int privotkey = 0;
if(low<high)
{
privotkey = partition(a, low, high);
quick_sort(a, low, privotkey-1);
quick_sort(a, privotkey+1, high);
}
}
int main (int argc, char **argv)
{
int a[10] = {3, 1, 5, 7, 2, 4, 9, 6, 10, 8};
print(a, 10);
quick_sort(a, 0, 9);
print(a, 10);
return 0;
}