排序算法-----归并排序、计数排序
2018-03-12 20:12
274 查看
1. 归并排序
将待排序序列分成两个长度相同的子序列,对每个子序列进行排序,直至子序列剩余一个数,在将其合并成一个序列[b]具体步骤:[/b]
分组:将待排序序列一分为2,在将子序列进行划分,直至子序列只有一个元素
归并:将每个子序列进行排序,将排好序的两个子序列进行合并
算法分析
稳定性最稳定算法,归并和分组过程中都不会使元素的相对位置发生变化
时间复杂度
这里采用了二分的思想,使其效率有所提高,时间复杂度为O(nlgn)
空间复杂度
在归并的过程中需要开辟临时数组,故时间复杂度为O(n)
代码
void Merge(DataType* a, int left, int mid, int right) { DataType* tmp = (DataType*)malloc((right - left + 1)*sizeof(int)); assert(tmp); memset(tmp,0,(right - left + 1)*sizeof(int)); int index = 0; int begin1 = left, end1= mid;//第一个数组的范围 int begin2 = mid + 1, end2 = right;//第二个数组的范围 //选两个数组中较小的数据在tmp数组中 while (begin1 <= end1 && begin2 <= end2) { if (a[begin1] <= a[begin2]) { tmp[index++] = a[begin1++]; } else { tmp[index++] = a[begin2++]; } } //数组1中还有数据 if (begin1 <= end1) { while (begin1 <= end1) { tmp[index++] = a[begin1++]; } } //数组2中还有数据 if (begin2 <= end2) { while (begin2 <= end2) { tmp[index++] = a[begin2++]; } } //将临时数组的数据拷回原数组 index = 0; while (index < right - left + 1) { a[index+left] = tmp[index]; ++index; } free(tmp); } //归并排序 void MergeSort(DataType* a, int left, int right) { assert(a); if (left >= right) return; //分组 if (right - left + 1 > 5) { int mid = left + ((right - left) >> 1); MergeSort(a, left, mid); MergeSort(a, mid + 1, right); //归并 Merge(a, left, mid, right); } else { InsertSort(a+left, right - left + 1); } }
2.计数排序
计数排序又称为鸽巢原理,是对哈希直接定址法的变形应用[b]具体步骤:[/b]
遍历数组,统计待排序数组的范围range
开辟数组,大小为统计的范围,并初始化为0
遍历数组,统计每个数出现的次数
将统计好数组元素出现的次数保存在哈希表对应位置上,对应位置即为数组元素大小
注意:待排序数组中不能有负数
算法分析
稳定性不稳定,在将数字重新拷贝至原数组时,元素相对位置会发生改变
时间复杂度
时间复杂度为O(n)
空间复杂度
需要开辟空间,因此为O(n)
代码
//计数排序 void CountSort(DataType* a, size_t n) { assert(a); //统计待排序数组的范围 DataType max = a[0], min = a[n - 1]; for (size_t i = 0; i < n; ++i) { if (a[i] < min) { min = a[i]; } if (a[i]>max) { max = a[i]; } } size_t range = max - min + 1; //开辟范围大小的数组 DataType* count = (DataType*)malloc(sizeof(int)*range); assert(count); memset(count, 0, sizeof(int)*range); //统计每个数出现的次数 for (size_t index = 0; index < n; ++index) { count[a[index]]++; } //将数字拷至原数组中 size_t index = 0; for (size_t i = 0; i < range; ++i) { for (int j = 0; j < count[i]; ++j) { a[index++] = min + i; } } free(count); }
4000
相关文章推荐
- 笔试面试最常涉及到的12种排序算法(包括插入排序、二分插入排序、希尔排序、选择排序、冒泡排序、鸡尾酒排序、快速排序、堆排序、归并排序、桶排序、计数排序和基数排序)进行了详解。每一种算法都有基本介绍、算
- 【排序算法】归并排序原理及Java实现
- 【排序算法】归并排序原理及Java实现
- 排序算法(七):归并排序
- 几种排序算法 冒泡、快速排序、归并、选择排序等
- 排序算法大集锦_二路归并排序_2&3(分治思想)
- 排序算法(七):归并排序
- 排序算法八:归并排序
- 闲了,再写写排序算法,一个最麻烦的归并排序。
- 排序算法(五)-- 线性时间排序之计数排序
- 排序算法(4)--归并排序
- 排序算法(六)归并排序
- python实现排序算法二:归并排序
- 排序算法(七):归并排序
- 排序算法:归并排序
- 常见排序算法整理(三)----归并排序、快速排序
- 排序算法(计数排序,基数排序,桶排序)
- Java排序算法以及算法改进总结(计数排序、基数排序、桶排序)
- 排序算法(六)归并排序
- 排序算法大集锦_二路归并排序_2&3(分治思想)