各种排序算法汇总(插入排序:直接插入排序、折半插入排序、希尔排序)
来源:互联网 发布:淘宝权女朋友静雯 编辑:程序博客网 时间:2024/04/30 02:57
以下是我对常见的几种排序算法的总结并给出的代码,基于C++语言实现,存储格式是顺序表。本人才疏学浅,如果有错漏还请各位指正。
一、存储格式:顺序表
int *data;//存储数据(data[1...size]存储待排序序列,data[0]为临时单元)int size;//可存放容量
二、插入排序
1.直接插入排序:
(1)思路:当插入data[i](i>=2)时前面的data[1],data[2],...,data[i-1]已经排好序.这时用data[i]的排序码与data[i-1],data[i-2],...的排序码顺序进行比较,找到插入位置即将data[i]插入,原来位置上的对象向后顺移.
(3)时间复杂度:O(n^2)
(4)稳定性:稳定
(5)源代码:
//直接插入排序void SeqList::directInsertSort(){int i, j;for (i = 2; i <= size; i++){data[0] = data[i];//暂存j = i - 1;while (data[j] > data[0])//查找插入位置{data[j + 1] = data[j];--j;}data[j + 1] = data[0];//插入}}
(6)分析:简单直观,工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。直接插入排序不适用与数据量大的排序,但是数据量较小,例如量级小于千时,插入排序还是一个不错的选择。
2.折半插入排序(又叫二分查找插入排序):
(1)思路:思路与直接插入排序相同,只是在查找插入位置时用二分查找提高效率,是对直接插入排序的改进。
(2)空间复杂度:只需要一个记录的附加空间,即data[0]
(3)时间复杂度:折半插入排序的比较次数数量级为O(n*log(n)),移动记录的次数和直接插入排序一样数量级为O(n^2),所以折半插入排序的时间复杂度为O(n^2)
(4)稳定性:稳定
(5)源代码:
//折半插入排序void SeqList::halfInsertSort(){int i, j, low, high, mid;for (i = 2; i <= size; i++){data[0] = data[i];//暂存low = 1;high = i - 1;while (low <= high)//二分查找寻找插入位置{mid = (low + high) / 2;if (data[0] < data[mid])high = mid - 1;elselow = mid + 1;}for (j = i - 1; j >= low; j--)//依次后移data[j + 1] = data[j];data[low] = data[0];//插入}}
(6)分析:优劣点与直接插入排序相同。
3.希尔排序(缩小增量排序):
(1)思路:把所有记录按一定的增量分组,对每组用直接插入排序算法排序,随着增量的减少,各分组中包含的记录将越来越多,当增量减少至1时,所有记录序列变成一个组。由此可见,希尔排序巧妙地利用原有子序列的有序性。步长的选择是希尔排序的关键,一般增量取d1=n/2,di+1=di/2(Shell的取法),已知的最好步长序列是由Sedgewick提出的(1, 5, 19, 41, 109,...)。注意最后一个增量必须为1
一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size
而不是i++
)。
例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:
13 14 94 33 8225 59 94 65 2345 27 73 25 3910
然后我们对每列进行排序:
10 14 73 25 2313 27 94 33 3925 59 94 65 8245
将上述四行数字,依序接在一起时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:
10 14 7325 23 1327 94 3339 25 5994 65 8245
排序之后变为:
10 14 1325 23 3327 25 5939 65 7345 94 8294
最后以1步长进行排序,此时就是简单的插入排序了(实例取自维基百科点击打开链接)(2)空间复杂度:只需要一个记录的附加空间,即data[0]
(3)时间复杂度:Shell算法的性能与所选取的分组长度序列有很大关系。只对特定的待排序记录序列,可以准确地估算关键词的比较次数和对象移动次数。想要弄清关键词比较次数和记录移动次数与增量选择之间的关系,并给出完整的数学分析,至今仍然是数学难题。
(4)稳定性:不稳定
(5)源代码:
//希尔排序void SeqList::shellSort(){ int i, j, gap; gap = size / 2; //初始步长 while (gap >= 1) //减小步长直至为1(变为一般的直接插入排序) { for (i = gap + 1; i <= size;i++) { data[0] = data[i]; //暂存以及岗哨 j = i - gap; while (data[j] > data[0]) //依次后移 { data[j + gap] = data[j]; j -= gap; } data[j + gap] = data[0]; //插入 } gap /= 2; //减小步长 }}
- 各种排序算法汇总(插入排序:直接插入排序、折半插入排序、希尔排序)
- 排序算法--直接插入排序、折半插入排序、希尔排序
- 插入排序(希尔排序、直接插入、折半插入排序)
- 插入排序:直接插入排序,折半查找排序,希尔排序
- java实现排序算法之插入排序(直接插入排序,折半插入排序,希尔排序)
- 排序算法——插入排序(直接插入排序、折半插入排序、希尔排序)
- 排序算法(堆排序,直接插入排序,折半插入排序,希尔排序)
- 直接插入排序 && 折半插入排序 && 希尔排序
- 直接插入排序,折半插入排序,希尔排序
- 直接插入排序、折半插入排序、希尔排序
- 插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)
- 插入排序(直接插入排序,折半插入排序,2路插入排序,希尔排序)
- 插入排序:直接插入, 折半插入,希尔插入
- 插入排序-直接插入排序 希尔排序
- 内部排序之插入排序:直接插入排序,折半插入排序,希尔排序
- 插入排序算法--直接插入算法,折半排序算法,希尔排序算法(C#实现)
- Java排序算法总结之(一)——插入排序(直接插入排序、折半插入排序、希尔排序)
- 排序算法汇总(选择排序 ,直接插入排序,冒泡排序,希尔排序,快速排序...)
- 自定义OpenFileDialog
- Android多媒体学习六:利用Service实现背景音乐的播放
- 刷leetcode:Reverse Integer
- 线程池处理多线程
- 吐槽支付宝红包:逼公鸡下蛋的后果
- 各种排序算法汇总(插入排序:直接插入排序、折半插入排序、希尔排序)
- 判断物体是否在视角内
- git提交到远程版本库失败
- 刷leetcode:String to Integer (atoi)
- Eclipse Maven Svn整合
- rtmfp流媒体-部分关键协议介绍
- 结构体与业务
- android 电容屏(二):驱动调试之基本概念篇
- Android MediaPlayer使用注意