1.1插入排序【直接插入排序、折半插入排序、希尔排列】

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<stdio.h> /*希尔排列*/ void Shellsort(int r[],int n) { int i,j,d,temp; d=n/2; /*设置初值*/ while(d>=1) { for(i=d+1;i<=n;i++) { j=i-d; while(j>0) { if (r[j]>r[j+d]) { temp=r[j]; /*将 r[j]与 r[j+d]进行交换*/ r[j]=r[j+d]; r[j+d]=temp; j=j-d; /**/ } else j=0; } } d=d/2; /*减小间隔值*/ } }
初 始 关 键 字 : r[1] 47 r[2] 55 r[3] 10 r[4] 40 r[5] 15 r[6] 94 r[7] 5 r[8] 70
(1) 第 一 趟 排 序 ( d = 4:)分 4 组 , 组 内 采 用 直 接 插 入 排 序 法 。 {47 15} {55 {10 {40 结 果 : 15 55 5 40 47 (2) 第 二 趟 排 序 ( d = 2 ) : 分 2组 , 组 内 采 用 直 接 插 入 排 序 法 。 {15 5 47 {55 40 结 果 : 5 40 10 55 15
希尔排序 希尔排序(Shell’s Sort)也称为“缩小增量法排序” ,是由 D.L.Shell 对直接插入排序进行改进后提 出来的。其基本思想是:不断地把待排序的一组记录按间隔值分成若干小组,分别进行组内直接插入 排序,待整个序列中的记录“基本有序”时,再对全体记录进行依次直接插入排序。 对间隔值(用 d 表示)的取法有多种,希尔提出的方法是:d1=[n/2],di+1=[di/2],最后一次排序时 间的间隔值必须为 1,其中 n 为记录数。
r[0] 初始序列: 第一趟(mid= 1) : 第二趟(mid= 1) : 第三趟(mid= 2,1) : 第四趟(mid= 2,1) : 岗哨 6 15 7 3
r[1] [20] [6 [6 [6 [3
r[2] 6 20] 15 7 6
r[3] 15 15 20] 15 7
r[4] 7 7 7 20] 15
94} 5} 94 10 10} 94 70 47 47 70 70} 94 94} 94 70} 70
(3) 第 三 趟 排 序 ( d = 1 ) : 整 个 数 据 合 成 1 组 , 采 用 直 接 插 入 排 序 法 。 {5 40 10 55 15 70 最 后 结 果 : 5 10 15 40 47 55
r[2] 6 20] 15 7 6 6
r[3] 15 15 20] 15 7 6
百度文库
r[4] 7 7 7 20] 15 7
r[5] 3 3 3 3 20] 15
r[6] 6 6 6 6 6 20]
#include<stdio.h> /*直接插入排序*/ void Insertsort(int r[],int n) /*对 r[1]~r[n]进行插入排序*/ { int i,j; for(i=2;i<=n;i++) { r[0]=r[i]; /*待插入记录送入岗哨*/ j=i-1; while (r[0]<r[j]) { r[j+1]=r[j]; j--; } r[j+1]=r[0]; /*r[0]插入合适位置*/ } } void main() { int a[7]={0,20,6,15,7,3,6},i; Insertsort(a,6); for(i=1;i<7;i++) printf("%-5d",a[i]); } 算法分析:直接插入排序的比较次数取决于原记录序列的有序程度。如果原始记录的关键字正好 为递增顺序时,比较次数最少为 n-1 次;如果为递减顺序时,比较次数最多,为(n-1)(n+2)/2 次,因 此,直接插入排序的时间复杂度为 O(n2)。
r[5] 3 3 3 3 20]
#include<stdio.h> /*折半插入排序*/ void Binsort(int r[],int n) { int i,j,low,high,mid; for(i=2;i<=n;i++) { r[0]=r[i]; low=1; high=i-1; /*设置查找区间上、下界*/ while(low<=high) { mid=(low+high)/2; if(r[0]<r[mid]) high=mid-1; /*插入点在前半区*/ else low=mid+1; /*插入点在后半区*/ } for(j=i-1;j>=low;j--) r[j+1]=r[j]; /*记录后移*/ r[low]=r[0]; /*插入*/ } } void main() { int a[6]={0,20,6,15,7,3 },i; Binsort(a,5); for(i=1;i<6;i++) printf("%-5d",a[i]); } 算法分析:折半插入排序的比较次数比直接插入排序的少,而移动次数相同,因此,总的时间 复杂度仍为 O(n2),另外,折半插入排序也是一种稳定的排序方法。
插入排序
直接插入排序 直接插入排序是最简单的排序方法之一。其基本思想是:在有序区中进行顺序查找,以确定插入的 位置,然后移动记录腾出空间,以便插入关键字相应的记录。
初始序列: 第一趟: 第二趟: 第三趟: 第四趟: 第五趟:
r[0] 岗哨 6 15 7 3 6
r[1] 20 [6 [6 [6 [3 [3
折半插入排序 折半插入排序是直接插入排序的改进,它提高了查找插入位置的速度。基本思想是:若要插入一 个记录,可先对有序的记录序列折半,确定要插入记录的位置在前一半序列,还是在后一半序列中, 不断地对有序的记录序列折半,最后找到合适的插入位置。 具体过程为:设置一个头指针 low 和一个尾指针 high,它们分别指向待查区间的头和尾,用 low 和 high 的值可以计算出中间记录的位置,用 mid 指示,mid=(low+high)/2。每次将待查记录的关键字 r[i].key 与 r[mid].key 作比较;若 r[i].key>r[mid].key,令 low=mid+1,继续查找;若 r[i].key<r[mid].key, 令 high=mid-1,继续查找,依次类推,直到查找到适当插入位置。
void main() { int a[9]={0,47,55,10,40,15,94,5,70},i; Shellsort(a,8); for(i=1;i<9;i++) printf("%-5d",a[i]); } 该算法通过三重循环来实现,外循环由不同间隔值 d 来控制,直到 d=1 为止,中间循环是在某个 d 值下对各组进行排序,用变量 i 控制。 可以看出,希尔排序实际上是对直接插入排序的一种改进,它的排序速度一般要比直接插入排序 快。希尔排序的时间复杂速度取决于所取的间隔,一般认为是 O(n lb n)。希尔排序是一个较复杂的问 题,并且它还是一种不稳定的排序方法。
相关文档
最新文档