插入排序与shell排序(希尔排序)

1 .插入排序的过程如同我们平时打扑克牌取牌插入的过程,不断将取出的扑克牌插入已经排好的地方。

插入排序过程初始有序区间大小为1,取出无序区间的首元素,查找有序区间的合适位置,进行插入。不断重复上述过程,即可完成操作。

图解示例

 1 //插入排序
 2 //karllen @2015
 3 void insertSort()
 4 {
 5      int i ,j ,temp;
 6      for(i = 1;i<n;++i)  //从第二个元素开始插入
 7      {
 8            temp = a[i];     //a[i]会被覆盖,临时保存
 9            j = i - 1;
10            while(j>=0&&a[j]>temp) //边移动边比较
11            {
12                  a[j+1] = a[j];
13            }
14            a[j+1] = temp;
15       }
16 }

2 .shell 排序算法是插入排序算法的一种,希尔排序先要将排序的一组数据按照某个增量分成若干组,相隔增量个的元素组成一组分别进行

插入排序,然后缩小增量,不断重复上述过程。直到将增量减小到1时,整个要排序的结果只能分成一组,并对其进行插入排序,即可完成。

图解示例:

取增量组为{3,2,1};

增量为3时,分为三组{70,10,90,60},{30,80,100,45},{40,20,75}分别进行插入排序,结果为

{10,60,70,90}

{30,45,80,100}

{20,40,75}; 执行完增量为3的分组插入排序后,结果为{10,30,20,60,45,40,70,80,75,90,100}局部有序性增强

增量为2时,{10,30,40,60,45,20,70,80,75,90,100}被分为两组,{10,20,45,70,75,100},{30,60,40,80,90}分别进行插入排序,结果为

{10,20,45,70,75,100}

{30,40,60,80,90};执行为增量为2的分组插入排序后,结果为{10,30,20,40,45,60,70,80,75,90,100}局部有序性进一步增强。

最后执行增量为1的直接插入排序,结果为{10,20,30,40,45,60,70,75,80,90,100}至此shell排序结束。

要点:分组进行插入排序的过程目的是使数据朝着局部有序的方向发展。

这里涉及增量的选取,增量的选取理论上应该是两两互素的。

代码如下:

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
// karllen
//2015 

void shellSort(int *a,int length);    //希尔排序

int main(int argc, char** argv)
{
    int a[] = {70,30,40,10,80,20,90,100,75,60,45};

    shellSort(a,11);

    for(int i = 0;i<11;++i)
    {
        std::cout<<a[i]<<" ";
    }

    return 0;
}

void shellSort(int *a,int length)      //希尔排序
{
    for(int incrt = length/2; incrt>0;incrt /= 2)
    {
        for(int i = 0;i<incrt;++i)     //依次排序不同增量构成的子序列
        {
            /*int j = i+incrt;
            int r;
            while(j<length)            //普通插入排序,先比较后移动
            {
                r = i;
                while(a[j]>a[r])
                {
                    r = r+incrt;
                }
                if(r!=j)
                {
                    int temp = a[j];
                       int k = j;
                       while(k>=r)
                    {
                           a[k] = a[k-incrt];
                        k -= incrt;
                       }
                    a[r] = temp;
                }
                j = j+incrt;
            }    */
            //改进后的直接插入排序,边移动边比较。
            int j = i+incrt;
            int r,temp;
            while(j<length)
            {

                r = j-incrt;
                temp = a[j];
                while(r>=0 && a[r]>temp)   //从后往前边移动边比较
                {
                    a[r+incrt] = a[r];
                    r = r-incrt;
                }
                a[r+incrt] = temp;         // 插入
                j = j+incrt;               // 转入下一元素的插入过程
            }
        }
    }
}

测试结果:

书到用时方恨少,是非经过不知难。 博观而约取,厚积而薄发。@karllen 每天进步一点点。

时间: 2024-10-15 16:34:28

插入排序与shell排序(希尔排序)的相关文章

Shell Sort(希尔排序)

近日学习了Shell Sort,也就是希尔排序,也称递减增量排序算法.在1959年由DL.Shell提出于1959年提出,由此得名. 此版本算法是在插入排序(Insertion Sort)基础上,将数组分成了h份(gap).也就是在数组中每隔h个数取出一个数,为一个子数组.先在子数组上进行排序,然后不断减小h的大小,直到h == 1 时,也就是完全变成插入排序的时候,排序完成. 算法复杂度取决于h(步长/步进)的选择,在最差的时候,也就是h == 1的时候,希尔排序就变成了插入排序,复杂度为O(

排序算法3--插入排序--希尔排序(缩小增量排序)

希尔排序(缩小增量排序) 希尔排序(Shell Sort)是插入排序的一种.也称缩小增量排序,是直接插入排序算法的一种更高效的改进版本. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序.因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高. 以n=10的一个数组4

排序——希尔排序

希尔排序(Shell Sort)是插入排序的一种.是针对直接插入排序算法的改进.该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组.所有距离为d1的倍数的记录放在同一个组中.先在各组内进行直接插入排序:然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<-<d2<d1),即所有记录放在同一组中进行直接插入排序为止. 希尔排序的实现代码: #inclu

常见排序集合(冒泡排序,选择排序,直接插入排序,二分插入排序,快速排序,希尔排序,归并排序)

一下是一些常见的排序算法: 交换元素(后面算法都有用到): // 交换元素 private static void swap(int[] a, int i, int j) { int temp; temp = a[i]; a[i] = a[j]; a[j] = temp; } 冒泡排序(有优化): // 冒泡排序(优化①,②,③,④) private static void bubbleSort(int[] a) { boolean flag = false;// ①表示整个序列是无序的 for

排序之插入排序:直接插入和希尔排序

一.插入排序 1.思想:原理类似抓扑克牌,在有序表中进行插入和查找,插入合适的位置时,之后的元素需要往后移动 2.时间复杂度: 最好:O(N),正序情况,只有比较时间,无移动时间 最坏:O(N2),逆序情况 平均:O(N2) 3.辅助空间:O(1) 4.稳定性:稳定 5.适用场合:适用于初始序列基本有序的情况,或者n小的时候,插入排序效率高 1 public static void insertSort(int[] a) { 2 int target,i,j; 3 for(j = 1;j<a.l

python排序-希尔排序

Shell 排序利用分组加速部分有序数组排序,分组定长跳跃冒泡 希尔排序的时间性能优于直接插入排序的原因: ①当文件初态基本有序时直接插入排序所需的比较和移动次数均较少. ②当n值较小时,n和 n^2 的差别也较小,即直接插入排序的最好时间复杂度O(n)和最坏时间复杂度0( )差别不大. ③在希尔排序开始时增量较大,分组较多,每组的记录数目少,故各组内直接插入较快,后来增量di逐渐缩小,分组数逐渐减少,而各组的记录数目逐渐增多,但由于已经按di-1作为距离排过序,使文件较接近于有序状态,所以新的

经典排序——希尔排序

感谢太原理工大学的算法演示:http://www.tyut.edu.cn/kecheng1/site01/suanfayanshi/shell_sort.asp 在希尔排序中主要是要明白在最底层是通过一次又一次的插入排序来实现的.每次都看成是h(k)个独立的数组,进行插入排序,然后循环h(k-1),h(k-2).....h(1): 代码如下:如果gap=1:那就是最后的插入排序了,不明白插入排序可以看我的插入排序 1 public static void Shell(int [] test){

数据结构(七)排序---希尔排序

图解排序算法(二)之希尔排序 定义 希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法.希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一. 希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序:随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止. 基本有序:小的关键字基本在前面,大的基本在后面,不大不小的基本在中间 基本思想 简单

大话算法-排序-希尔排序

希尔排序,是插入排序的改进版本,又叫缩小增量排序. 1.首先取一个整数gap默认是2,将元素分为gap个子序列,所有间隔为gap的元素放在一个子序列中 2.然后在每个子序列终实现直接插入排序,然后缩小间隔gap,直到gap缩小到1 3.最后一步执行插入排序,直到数据完成排序. def shell(alist): length = len(alist) if length <= 1: return alist # 初始步长 gap = length // 2 while gap > 0: for

数据结构排序-希尔排序

希尔排序也是插入排序的一种,但是它效率高于直接插入排序. 基本思想是: 首先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组.所有距离为d1的倍数的记录放在同一个组中.先在各组内进行直接插入排序: 然后,取第二个增量d2<的重复上述的分组和排序,直到所取的增量dt=1. 增量序列尤其关键,一般的初次取序列的一半为增量,以后每次减半,直到增量为1. 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int n; 5 6 /*