排序算法(1)——冒泡排序
冒泡排序
冒泡排序可以说是最简单的一种排序,当然,复杂度也是最高的
冒泡排序的实现过程:两两之间相互比较,当前者比后者大的时候,两者交换(假设是升序排列)。
那么给出简单的冒泡排序算法:
#define MAXSIZE 10
void swap(SqList *L, int i, int j) { int temp = L->r[i]; L->r[i] = L->r[j]; L->r[j] = temp; } typedef struct { int r[MAXSIZE + 1]; int length; } SqList; void BubbleSort0(SqList *L) { int line, col; for (line = 0; line < L->length - 1; line++) { for (col = line + 1; col < L->length; col++) { if (L->a[line] > L->a[col]) { swap(L, line, col) } } }
这是最简单的一种排序算法,也是我们所能够写出来的,不正宗的冒泡排序。
下面给出一种正宗的冒泡排序:
void BubbleSort1(SqList *L) { int line, low; for (line = 0; line < L->length - 1; line++) { for (low = L->length - 1; low >= line; low--) { if (L->r[low] > L->r[low + 1]) { swap(L, line, low); } } } }
显然,这种排序算法相较于上一种就好了很多,后面的数据经过比较逐渐的浮上(前)来,并且稍微小一点的(比浮上来的第一个略大)的数据也经过这次排序而浮到前面上来。而上一种是每一个与其后面的每一个都进行一次对比。
冒泡排序还能不能改进呢?
答案是能。
设想一下:如果没有数据交换或者数据交换很少的话,会是怎样的一种情况?
比方说 {2, 1, 3, 4, 5, 6, 7, 8, 9},对它进行排序,显然,除了1 和 2交换之外,没有其他的数据进行交换,但是如果沿用上面的算法,尽管不用进行数据交换,我们还是要进行for循环,将两两之间进行比较(毕竟计算机不知道这个数组到底有没有序)。那么,我们就可以想一个改进方法,如果没有数据交换,就不进行比较。
具体改进代码如下:
void BubbleSort2(SqList *L) { int line, col; bool flag = True; for (line = 0; line < L->length - 1 && flag; line++) { flag = False; for (col = L->length - 1; col >= line ; low--) { if (a[col] > a[col + 1]) { swap(L, col, col + 1); flag = True; //如果有数据交换,那么flag 就为真,如果没有,就为假 } } } }
以上。
先写这么点。。
因为舍友太过吵闹无法入睡,所以才写的。。。
真尼玛悲伤。。
差点忘了复杂度分析:
这个算法的复杂度是O(n^2),具体分析如下:
最糟的状况,就是原排序和我们所要的排序完全相反,比如说我们要的是{1, 2, 3, 4, 5},而原来的数列却是{5, 4, 3, 2, 1},那么这样的话,每一步比较都需要换位,第一次需要比较并移动4次,第二个需要比较并移动3次,第三个需要比较并移动两次,第四个需要比较并移动1次,总共是10次,也就是 (n - 1) + (n - 2) + (n - 3) + ......+ 1 = n(n - 1) / 2。
而最好的情况,当然是一次都不用移动啦,这个时候算法复杂度就是O(n)。