18、插入排序,快速排序
来源:互联网 发布:淘宝 比较好的手机店 编辑:程序博客网 时间:2024/05/22 05:14
1、插入排序:每次从无序数据集中取出一个元素,扫描已排好的数据集,把这个元素插入有序集的合适位置。
特点:简单,但不适合处理大型数据集,不需要额外空间,最坏O(n2),在增量排序中非常高效。
int issort(void *data, int size, int esize, int (*compare)(const void *key1, const void *key2)){ int i, j; void *key; char *a = data; if((key = (char *)malloc(esize)) == NULL) return -1; for(j = 1; j < size; j++) { //key暂存当前需要移动的数据 memcpy(key, a[i * esize], esize); i = j - 1; //如果key小,向左和下一个比较 while((i >= 0) && (compare(&a[i * esize], key) > 0)) { memcpy(&a[(i + 1) * esize], &a[i * esize], esize); i--; } //把该数插入比左边较小数的右边 memcpy(&a[(i + 1) * esize], key, esize); } free(key); return 0;}
2、快速排序:一种分治排序算法。
分:将未排序的支票分为两堆,其中一堆小于等于某个数,另一堆大于某个数。
治:重复划分,递归快速排序直到每堆只有一个。
合:对分割部分排序直至完成。
特点:适合大数据,不需要额外空间,最坏O(n2),平均O(nlgn)。如果分割值选的不好,性能会很差。一个有效方法为随机选择法。还可以改进随机选择法:随机选取3个数,取3个元素的中间值。
//i, k 初始值为 0 和 size - 1, 返回分好的边界点位置 //partition完成分割值的选取,把一堆分成以分割值为边界的两堆。 static int partition(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)){ char *a = data; void *pval, *temp;//pval存放边界值,temp交换中介 int r[3]; if((pval = malloc(esize)) == NULL) return -1; if((temp = malloc(esize)) == NULL) { free(pval); return -1; } r[0] = (rand() % (k - i + i)) + i; r[1] = (rand() % (k - i + i)) + i; r[2] = (rand() % (k - i + i)) + i; issort(r, 3, sizeof(int), compare); memcpy(pval, &a[r[1] * size], esize); i--; k--; while(1) { do { k--; }while(compare(&a[k * esize], pval) > 0); do { i++; }while(compare(&a[i * esize], pval) < 0); //找完 if(i >= k) { break; } //大于边界值的放右边,小于边界值的放左边 else { memcpy(temp, &a[i * esize], esize); memcpy(&a[i * esize], &a[k * esize], esize); memcpy(&a[k * esize], temp, esize); } } free(pval); free(temp); return k; } //划分即排序 int qksort(void *data, int size, int esize, int i, int k, int (*compare)(const void *key1, const void *key2)){ int j; while(i < k) { if((j = partition(data, esize, i, k, compare)) < 0) return -1; if(qksort(data, size, esize, i, j,compare)) return -1; i = j + 1; } return 0;}
3、快速排序的例子-目录列表
int directls(const char *path, Directory **dir){ DIR *dirptr; Directory *temp; struct dirent *curdir; int count, i; //先打开路径 if((dirptr = opendir(path)) == NULL) return -1; *dir = NULL; count = 0; //先把每个文件的名字读到字符串数组dir中 while((curdir = readdir(dirptr)) != NULL) { count++; if((temp = (Directory *)realloc(*dir, count * sizeof(Directory))) == NULL) { free(*dir); return -1; } else { *dir = temp; } strcpy( ((*dir)[count - 1]).name, curdir->d_name ); } closedir(dirptr); if(qksort(*dir, count, sizeof(Directory), 0, count - 1, compare_dir) != 0) return -1; return count;}
阅读全文
0 0
- 18、插入排序,快速排序
- 插入排序,快速排序
- 快速排序 插入排序
- 快速排序+插入排序
- 插入排序----快速排序
- 快速排序和插入排序
- 插入排序和快速排序
- 插入排序 和 快速排序
- 快速排序与插入排序
- java 插入排序+快速排序
- 插入排序与快速排序
- 插入排序与快速排序
- 快速排序和插入排序
- 快速排序和插入排序
- 快速排序和插入排序
- 插入、归并、快速排序
- 插入,希尔,快速排序
- 【排序总结--插入、快速】
- Linux内核定时器
- Muduo 设计与实现之一:Buffer 类的设计
- 我教你使用Spring Cloud和Docker构建微服务
- 关于windows server 2008 ftp搭建
- mysql------基础及常见SQL技巧
- 18、插入排序,快速排序
- CommonJS规范
- 关于接口测试的一些总结
- WebView 基础使用
- Mac上使用 sunny- ngrok
- 基于MTK平台kpd 驱动解析
- 内网映射到外网的工具ngrok使用
- 欢迎使用CSDN-markdown编辑器
- Ajax请求出现“Method Not Allowed 405”