文档章节

排序算法(3)--插入排序&希尔排序

haoran_10
 haoran_10
发布于 2016/07/15 16:37
字数 800
阅读 8
收藏 0
点赞 0
评论 0

、插入排序

 (1)、主要思路:

  1. 假设数组分为两部分,有序部分【0~i-1】,无序部分【i~N】。初始有序部分只有一个元素。
  2. 从有序部分【0~i-1】中找到一个值小于(或大于)数组【i】的位置,即为将要排序的数据
  3. 把数组【i】插入到适当的位置,其他的数据往后转移

 

(2)、代码实现:

public void sort(int[] arr) {
	for(int i=1;i<arr.length;i++){
		
		int insertValue = arr[i];
		int j;
		
		for(j=i-1;j>=0;j--){//1.从arr[i-1]~arr[0]数组之间,找到一个位置
			if(insertValue > arr[j]){
				break;
			}
		}
		
		//2.如果j==i-1,说明不需要调换,恰好处于排序的位置
		if(j==i-1){
			continue;
		}
		
		//3.找到一个恰好的位置
		for(int k =i-1;k>j;k--){
			arr[k+1] = arr[k];
		}
		arr[j+1] = insertValue;
	}
}

 

 

二、希尔排序

 希尔排序是对插入排序的一种改进算法,是一种分组插入排序,又称为缩小增量排序法。

希尔排序的时间复杂度与增量(即,步长gap)的选取有关。例如,当增量为1时,希尔排序退化成了直接插入排序,此时的时间复杂度为O(N²),而Hibbard增量(N/2)的希尔排序的时间复杂度为O(N3/2)。

 

(1)、主要步骤:

  1. 对一个数组长度为N的数组,取一个小于N的整数gap(gap称为步长)
  2. 根据该步长将数组分为若干个子数组,所有距离为gap的倍数的记录放在同一个子数组
  3. 对每个子数组进行插入排序
  4. 然后缩减gap的值,并重复上面的分组和排序
  5. 当gap==1时,整个数组就是有序的

 

(2)、演示过程:

下面以数列{80,30,60,40,20,10,50,70}为例,演示它的希尔排序过程。

 

第1趟:(gap=4)



 

 

当gap=4时,意味着将数列分为4个组: {80,20},{30,10},{60,50},{40,70}。 对应数列: {80,30,60,40,20,10,50,70}
对这4个组分别进行排序,排序结果: {20,80},{10,30},{50,60},{40,70}。 对应数列: {20,10,50,40,80,30,60,70}


第2趟:(gap=2)



 

 

当gap=2时,意味着将数列分为2个组:{20,50,80,60}, {10,40,30,70}。 对应数列: {20,10,50,40,80,30,60,70}
注意:{20,50,80,60}实际上有两个有序的数列{20,80}和{50,60}组成。
          {10,40,30,70}实际上有两个有序的数列{10,30}和{40,70}组成。
对这2个组分别进行排序,排序结果:{20,50,60,80}, {10,30,40,70}。 对应数列: {20,10,50,30,60,40,80,70}

 

第3趟:(gap=1)



 

 

当gap=1时,意味着将数列分为1个组:{20,10,50,30,60,40,80,70}
注意:{20,10,50,30,60,40,80,70}实际上有两个有序的数列{20,50,60,80}和{10,30,40,70}组成。
对这1个组分别进行排序,排序结果:{10,20,30,40,50,60,70,80}

 

 

(3)、代码实现

public void sort(int[] arr) {
	// gap为步长,每次减为原来的一半。
	for (int gap = arr.length / 2; gap > 0; gap /= 2) {
		// 共gap个组,对每一组都执行直接插入排序
		for (int i = 0; i < gap; i++) {
			group_sort(arr, arr.length, i, gap);
		}
	}
}

private void group_sort(int arr[], int n, int i, int gap) {
	for (int j = i + gap; j < n; j += gap) {
		// 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。
		if (arr[j] < arr[j - gap]) {
			int tmp = arr[j];
			int k = j - gap;
			while (k >= 0 && arr[k] > tmp) {
				arr[k + gap] = arr[k];
				k -= gap;
			}
			arr[k + gap] = tmp;
		}
	}
}

 

© 著作权归作者所有

共有 人打赏支持
haoran_10
粉丝 25
博文 88
码字总数 80846
作品 0
杭州
程序员
算法系列【希尔排序】篇

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 1. 平方阶 (O(n2)) 排序各类简单排序:直接插入...

湖南小影 ⋅ 2017/05/18 ⋅ 0

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 1. 平方阶 (O(n2)) 排序各类简单排序:直接插入...

湖南小影 ⋅ 2017/05/18 ⋅ 0

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 1. 平方阶 (O(n2)) 排序各类简单排序:直接插入...

湖南小影 ⋅ 2017/05/18 ⋅ 0

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 1. 平方阶 (O(n2)) 排序各类简单排序:直接插入...

湖南小影 ⋅ 2017/05/18 ⋅ 0

算法系列【希尔排序】篇

常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。用一张图概括: 关于时间复杂度: 1. 平方阶 (O(n2)) 排序各类简单排序:直接插入...

湖南小影 ⋅ 2017/05/18 ⋅ 0

插入排序,希尔排序,堆排序详解

本文将介绍三种排序算法--插入排序,希尔排序,堆排序。本文所有例子都是使用升序 一.插入排序 算法思想 维护一个有序数组,将要插入的数据与有序数组自最后一个元素直到合适位置的数一一比较...

crazys_蘑菇 ⋅ 2016/05/23 ⋅ 0

5Python全栈之路系列之算法

ython全栈之路系列之算法 一个算法的优劣可以用空间复杂度与时间复杂度来衡量。 冒泡排序 冒泡排序(英语:Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法。它重复地走访...

余二五 ⋅ 2017/11/15 ⋅ 0

Java---插入类排序(直接插入排序,希尔排序)

Java—插入类排序(直接插入排序,希尔排序) Tags: 排序算法 直接插入排序 1.算法思想:其基本操作为将第i个记录插入到前面i-1个已经排好序的记录中 2.实现代码: 3.时间空间效率 (最好情况...

dorma_bin ⋅ 2017/12/13 ⋅ 0

数据结构之常见的排序算法c语言实现

常见的简单排序算法有冒泡排序、选择排序、插入排序、快排、堆排序、归并排序、希尔排序等,这些排序的理论在网上有很多,这就只给出常见的排序算法源码,上学时候写的,不足之处欢迎大家指正...

菏泽小朱 ⋅ 2016/12/11 ⋅ 0

数据结构-插入排序&希尔排序

一、插入排序 <1>介绍:插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入...

sssssuuuuu666 ⋅ 2017/12/03 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

一起读书《深入浅出nodejs》-node模块机制

node 模块机制 前言 说到node,就不免得提到JavaScript。JavaScript自诞生以来,经历了工具类库、组件库、前端框架、前端应用的变迁。通过无数开发人员的努力,JavaScript不断被类聚和抽象,...

小草先森 ⋅ 昨天 ⋅ 0

Java桌球小游戏

其实算不上一个游戏,就是两张图片,不停的重画,改变ball图片的位置。一个左右直线碰撞的,一个有角度碰撞的。 左右直线碰撞 package com.bjsxt.test;import javax.swing.*;import j...

森林之下 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部