python中的插入排序以及希尔排序

#算法和数据结构分析#

今天接着排序来讲:1.插入排序(selection sort)

2希尔排序(shell sort)

为何要将它们放在一起讲呢? 因为它们之间存在一定的联系.

那我们先来看看选择排序是什么???

一.选择排序(selection sort)

首先假设位置0处的元素是只含单个元素的有序子列表。从元素1到元素n-1,每一轮都将当前元素与有序子列表中的元素进行比较。在有序子列表中,将比它大的元素右移;每当遇到一个比它小的元素或抵达子列表终点的时候,就可以插入当前元素

python中的插入排序以及希尔排序_第1张图片

可能这么说,还是有些模糊,那么上代码

def selection_sort(alist):
    for index in range(1,len(alist)):
        currentvalue = alist[index]
        position = index
#index为新项,插入项

        while position > 0 and alist[position-1] > currentvalue:
                alist[position] = alist[position-1]
                position = position - 1
#比对,移动项,使始终空出一个位置留给插入项
        
        alist[position] = currentvalue
#最后结束一次while循环 插入新项

或者还有一种写法

def insertion_sort(alist):
    for i in range(1,len(alist)):
          currentvalue = alist[i]
          j = i - 1
#设插入值为currentvalue j作为引索

          while j >= o and currentvalue < alist[j]:
                alist[j+1] = alist[j]
                j = j - 1
#当前值若大于插入值,便向后移一位

#最后找到插入位置,完成一次循环           
          alist[j+1] = currentvalue
    return alist

原理:通过构建有序序列,对于未排序数据在已排序序列中从后向前scan(扫描),从而找到相应的位置并插入进去。

1.从第一个元素开始,该元素可以被认为已经被排序

2.取出下一个元素,在已经排序的元素序列中从后向前扫描

3.如果被扫描的元素(已排序)大于新元素,将该元素后移一位。

4.重复步骤3,直到找到已排序的元素小于或等于新元素的位置

5.将新元素扫描到该位置后

6.重复步骤2-5  直到for循环结束 return来结束函数 返回最终值

注意注意:一定要搞明白---插入排序,再来看希尔排序

希尔排序是更便捷的插入排序,基础是插入排序

二.希尔排序

希尔排序(shell sort)也叫“递减增量排序”,它对插入排序做了改进,将列表分成数个子列表,并对每一个子列表应用插入排序。

这里的关键就是,我们该如何区切分列表呢???
这里的切分并不是连续切分,而是使用增量(也可以叫步长(step))选取所有间隔为i的元素组成为子列表。

python中的插入排序以及希尔排序_第2张图片

为了进行希尔排序,我们有以下四个步骤:

1.间隔分组(总长度的一半)

2.组内排序

3.重新设置间隔分组(为前一次分组的一半)

4.插入排序

代码实现有两个部分

我们先来看第一个部分,分组吧

def shellsort(alist):
    sublistcount = len(alist) // 2 #取半

#不断对半,直到step为1
    while sublistcount > 0:
        for startposition in range(sublistcount):
            gapInsertionSort(alist,startposition,sublistcount)
#此处是进行子列表中的选择排序
        
         sublistcount = sublistcount // 2
#对原先的组进行再次取半    

其实我们求出的sublistcount再后面将会用作gap(步长)来使用

可以看到我们在for循环时,调用了一个函数gapInsertionSort()---这个是用来进行小组内的插入排序

那么我们来看看这个函数,它的代码又是如何呢?

def gapInsertionSort(alist,start,gap):
    for i in range(start+gap,len(alist),gap):
#设置插入值
        currentvalue = alist[i]
        position = i

#这里便与我们在上面说的插入排序相似
        while position > gap and\
            alist[position] > alist[currentvalue]:
                alist[position] = alist[position-gap]
                position = position - gap
            
            alist[position] = currentvalue

看似希尔排序可能没有插入排序好,因为最后一步要做完整的插入排序。但是,在事实上,列表已经做好了预处理的,则最后一步插入排序,不再需要进行多次的插入和比较。每一轮高效的子列表插入排序,为最后一步的完整列表插入排序做好了准备,最后一步,会非常高效

你可能感兴趣的:(算法,数据结构)