• 直接插入排序和希尔排序


    在学ruby,正好顺便把排序算法都复习一遍,先来看直接插入排序(insertion sort) 和 希尔排序 (shell sort)。

    直接插入排序比较简单,直接上代码:( 算法渐进时间复杂度 O(n2) )

    # insertion sort
    
    def insertion_sort(list)
    	return list if list.size <= 1
    
    	tmp = -1
    
    	1.upto(list.size - 1) do |i|
    		inserted = false
    		tmp = list[i]
    		puts(i)
    		(i - 1).downto(0) do |j|
    			puts(j)
    			if tmp >= list[j]
    				list[j+1] = tmp
    				inserted = true
    				puts "insert",(tmp),(j+1)
    			else
    				list[j+1] = list[j]
    			end
    			break if inserted
    		end
    	end
    
    	list
    end
    
    list = [3, 5, 22, 634, 4]
    puts(insertion_sort(list))
    

    直接插入排序算法时间复杂度和原数组有关:如果原数组基本有序就很快,反之如果原数组乱序或者逆序则达到最坏时间复杂度。基于以上原因,出现希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。

    希尔排序就是按照固定步长先对子数组排序,然后逐渐缩短步长,最后一次排序步长为1(此时相当于进行一次插入排序,因为此时数组已经基本有序,所以很快)。

    希尔排序最重要的部分是步长的选择。只要最终步长为1任何步长序列都可以工作。算法最开始以一定的步长进行排序。然后会继续以一定步长进行排序,最终算法以步长为1进行排序。当步长为1时,算法变为插入排序,这就保证了数据一定会被排序。(想了半天发现还是维基百科的描述最好理解 >_< )。

    而已知

    已知的最好步长序列由Marcin Ciura设计(1,4,10,23,57,132,301,701,1750,…) 这项研究也表明“比较在希尔排序中是最主要的操作,而不是交换。”用这样步长序列的希尔排序比插入排序堆排序都要快,甚至在小数组中比快速排序还快,但是在涉及大量数据时希尔排序还是比快速排序慢。

    另一个在大数组中表现优异的步长序列是(斐波那契数列除去0和1将剩余的数以黄金分割比的两倍的进行运算得到的数列):(1, 9, 34, 182, 836, 4025, 19001, 90358, 428481, 2034035, 9651787, 45806244, 217378076, 1031612713, …)

    而有了上述步长队列之后,只需要选择队列中小于原数组长度的步长中的最大者作为第一次希尔排序的步长即可。

     希尔排序代码:(ruby)

      
    # shell sort
    
    def shell_sort(list)
    	return list if list.size <= 1
    	
    	steps = [1, 4, 10, 23, 57, 132]
    	index = 0
    	while steps[index + 1] < list.size do
    		index += 1
    	end
    
    	index.downto(0) do |i|
    		step = steps[i]
    
    		step.upto(list.size - 1) do |j|
    			tmp = list[j]
    			#puts list.size if step == 4
    			k = j
    			while(k >= step && list[k - step] > tmp) do
    				list[k] = list[k-step]
    				k = k - step
    			end
    			list[k] = tmp
    		end
    	end
    
    	list
    end
    
    list = [23, 4, 56, 6, 5, 153, 2, 7, 98, 235, 2, 90, 20, 201, 6, 34, 47, 30]
    puts (shell_sort(list))
    

      

    详细介绍直接查看维基百科:http://zh.wikipedia.org/wiki/%E5%B8%8C%E5%B0%94%E6%8E%92%E5%BA%8F

  • 相关阅读:
    JSTL笔记(胖先生版)
    EL表达式(胖先生版)
    包装类-Character
    String定义与方法
    冒泡排序(大熊版)
    tomcat Manger App
    第一天
    剑指offer:面试题5、从尾到头打印链表
    剑指offer:面试题4、替换空格
    剑指offer:面试题3、二维数组中的查找
  • 原文地址:https://www.cnblogs.com/kimimaro/p/2341598.html
Copyright © 2020-2023  润新知