冒泡算法的改进
2013-12-20 23:03
218 查看
冒泡排序算法的思想:
首先将第一个记录的关键字和第二个关键字进行比较,若为逆序则将两个记录进行交换。
然后比较第二个记录和第三个记录的关键字,直至第n-1个记录和第n个记录进行比较为止,一趟过后最大的元素会沉入最底部。
然后进行第二趟排序,对前 n-1 个记录进行同样1、2的操作,结果就是关键字次大的记录被安排到n-1位置上。
依次进行第 i 趟排序,对前 n-i 个记录进行同样的1、2的操作,直到一趟没有进行过任何比较的操作,排序结束。
先看一下基础冒泡算法:
核心思想是每次选出最大的数沉入底部,直至没有数据可比较。
首先计算一下它的时间复杂度,这里以最坏的情况来计算的话:
(n-1)+(n-2)+……+ 1 + 0 = n*(n-1)/ 2 = O(n^2)
最好的情况就是已经排序好,不需要进行比较
首先看到其不足之一:就是频繁交换元素。如何避免,可以存放在一个合适的位置,精简算法一:
第二个是函数,这里使用了引用,可以减少指针使用的形参变量副本的创建,但是这里使用了inline,所以还是替换
测试程序:
首先将第一个记录的关键字和第二个关键字进行比较,若为逆序则将两个记录进行交换。
然后比较第二个记录和第三个记录的关键字,直至第n-1个记录和第n个记录进行比较为止,一趟过后最大的元素会沉入最底部。
然后进行第二趟排序,对前 n-1 个记录进行同样1、2的操作,结果就是关键字次大的记录被安排到n-1位置上。
依次进行第 i 趟排序,对前 n-i 个记录进行同样的1、2的操作,直到一趟没有进行过任何比较的操作,排序结束。
先看一下基础冒泡算法:
int BubbleSort(MergeType* L) { int i, j; for (i = 0; i <= L->len-1; i++) { for (j = 0; j < L->len-1-i; j++) { if (L->elem[j+1] < L->elem[j]) { SWAP(L->elem[j+1], L->elem[j] ); } } } return 0; }这里的MergeType类型如下:
typedef struct _SQLIST{ int* elem; int len; //实际长度 int size; //分配空间 }SqList, *pSqList; typedef _SQLIST MergeType;
核心思想是每次选出最大的数沉入底部,直至没有数据可比较。
首先计算一下它的时间复杂度,这里以最坏的情况来计算的话:
(n-1)+(n-2)+……+ 1 + 0 = n*(n-1)/ 2 = O(n^2)
最好的情况就是已经排序好,不需要进行比较
首先看到其不足之一:就是频繁交换元素。如何避免,可以存放在一个合适的位置,精简算法一:
int BubbleSortEx(MergeType* L) { int i = 0, j = 0; int max, temp; for (i = 0; i <= L->len-1; i++) { temp = L->elem[0]; max = 0; for (j = 1; j < L->len-i; j++) { if (L->elem[j] > temp) { temp = L->elem[j]; max = j; } } //printf("%d:%d \n", max, temp); swap(L->elem[L->len-1-i], L->elem[max] ); } return 0; }看到这里每次仍然需要频繁的进行赋值操作,当然只是微不足道的,但是赋值也会增加cpu执行的时间,所以精简算法二:
int BubbleSortEx(MergeType* L) { int i, j , max; for (int i = 0; i <= L->len-1; i++) { max = 0; for (j = 1; j < L->len-i; j++) { if (L->elem[j] > L->elem[max]) { max = j; } } //printf("%d:%d \n", max, L->elem[max]); swap(L->elem[L->len-1-i], L->elem[max] ); } return 0; }这里的两个swap是不一样的,当然也可以使用一样的,看如下具体的实现:
#define SWAP(a, b) \ { \ int temp = (a); \ (a) = (b); \ (b) = temp; \ }
inline void swap(int& a, int& b) { int temp = a; a = b; b = temp; }第一个是采用宏替换,当然主要是增加预处理的时间,主要是用宏会出现意想不到的错误
第二个是函数,这里使用了引用,可以减少指针使用的形参变量副本的创建,但是这里使用了inline,所以还是替换
测试程序:
int PrintList(MergeType *L); int ScanfList(MergeType *L, const int nScanfType = -1); int SortTest() { printf("--- %s ---\n", __FUNCTION__); MergeType pList; MergeType pT; pList.elem = (int*)malloc(sizeof(int)*10); pList.len = 10; pList.size = 10; ScanfList(&pList); /*输入数据*/ BubbleSortEx(&pList);/*冒泡排序*/ PrintList(&pList);/*输出数据*/ free(pList.elem); pList.elem = NULL; return 0; }数据输入:
int ScanfList(MergeType *L, const int nScanfType) { if (!L->elem) { return -1; } printf("Old List\t: "); for (int i = 0; i <= L->len; i++ ) { if( i == L->len ) { printf("\n"); break; } switch (nScanfType) { case 0: { break; } default: L->elem[i] = 11 * i - i * i; break; } printf("%d ", L->elem[i]); } return 0; }数据输出:
int PrintList(MergeType *L) { if (!L->elem) { return -1; } printf("Sort List\t: "); for (int i = 0; i <= L->len; i++ ) { if (i == L->len) { printf("\n"); break; } printf("%d ", L->elem[i]); } return 0; }
相关文章推荐
- [算法设计与分析]3.3.2标志量的妙用(冒泡算法改进+三个数的最小公约数)
- 改进版的冒泡排序(双向冒泡算法)
- 内部排序算法之二【改进的冒泡算法,鸡尾酒算法】
- 冒泡算法及改进(属于交换排序)
- 冒泡算法改进
- 快速排序算法(冒泡算法的改进)
- 二元冒泡排序(改进的冒泡算法)
- 改进的冒泡算法
- 关于冒泡算法的改进
- 改进的冒泡算法
- 冒泡算法的改进:用标志量来记录每趟交换数据的情况,如flag=0表示没有进行交换;
- 冒泡算法改进--双向冒泡算法 Double Bubble
- 冒泡算法改进
- Java排序算法--之冒泡算法改进
- 冒泡算法改进--双向冒泡算法 Double Bubble
- 鸡尾酒算法--冒泡算法的改进版
- 冒泡算法的改进具体实现
- 冒泡算法改进
- 使用JavaScript进行表单必填项目验证和改进