插入排序

希尔排序算法

橙三吉。 提交于 2020-04-07 09:46:46
前言 当待插入元素是一个很小(当需求是从小到大排序时,从大到小排序时此处为很大)直接插入排序需要移动较多次数,性能会很差。希尔排序解决了这一问题。 基本思想 希尔排序的基本思想: 把序列按下标的一定增量分组,对每组使用直接插入排序算法排序; 随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。 如果对直接插入排序不了解的朋友,可以看我的这篇文章: 详解直接插入排序算法 例子 给定数组arr为 [ 3 , 6 , 5 , 12 , 1 , 75 , 10 , -3, 0 ] 初始状态见下图: 定义变量 h 为增量,初始值为5 。 第一轮 根据增量设置成5组,颜色相同的为一组。 对每一组进行直接插入排序得到: 然后 h减半向下取整; 则 h = 3; 第二轮 根据增量设置成5组,颜色相同的为一组。 对每一组进行直接插入排序得到: 然后 h减半向下取整; 则 h = 1; 第三轮 增量为1,所有序列为一组。 插入排序后得到: h此时为1,全部有序,完毕。 由例子可知,每次都可以达到组内部分有序,大大减少了插入排序的移动开销。 代码 首先说下步长的选择: 步长的选择一般时这样的: int h = 1; while(h < arr.length / 2){ h = 2 * h + 1; } 即先把步长设置为1,只要 h 小于数组长度一半(向下取整

常见排序方法

不问归期 提交于 2020-04-03 14:55:14
比较常用的排序方法(升序): 冒泡排序: 最常用的排序方法。大体思路就是每次选出一个最大值,第二次选出次大值,基本上就是两个for循环。 鸡尾酒排序 :冒泡排序方法的变种,鸡尾酒排序,待排序数组首先从0->n-1找出最大值,然后n-2->0找出最小值,然后再从1->n-2找次大值……依次类推……一个while循环,里面套两个for循环即可。 奇偶排序 :也是冒泡排序的变种。一个while循环,里面两个for循环,但是一个for循环从0开始,一个从1开始,每次加2,比较相邻两个数值大小。 快速排序 :是分之思想的一种体现。对于一个待排序队列,首先选择一个 基准 ,扫描数据,大于这个基准数据的元素放在右侧,小于的放在左侧,然后左侧和右侧的数据又是待排序队列,再分别选择基准……递归下去,知道全部都是有序的。 插入排序: 是一种比较直观的排序方法,从待排序队列中构建有序队列,把剩余的待排序数据插入到有序队列中。 希尔排序 :分步长排序法,对相隔步长的数据分别进行排序,然后减小步长,直至步长为1,主要可以减少数据的移动次数。 选择排序: 选择一个最大元素放入队尾,然后从剩余的元素中选择最大的放入队尾的前一位置,直到待排序数组中只有一个元素为止。 堆排序算法 :选择排序的一种,不停的构建大(小)顶堆,然后取出顶,得到有序序列。 归并排序 :也是典型的分治法思想的应用

C/C++ 数据结构之算法(面试)

独自空忆成欢 提交于 2020-03-27 08:16:46
数据结构中的排序算法。 排序算法的相关知识: (1)排序的概念:所谓排序就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来。 (2)稳定的排序方法:在待排序的文件中,若存在多个关键字相同的记录,经过排序后这些具有相同关键字的记录之间的相对次序保持不变,该排序方法是稳定的。相反,如果发生改变,这种排序方法不稳定。 (3)排序算法的分类(分为5类):插入排序、选择排序、交换排序、归并排序和分配排序。 (4)排序算法两个基本操作:<1>比较关键字的大小。 <2>改变指向记录的指针或移动记录本身。 具体的排序方法: 插入排序 <1>插入排序(Insertion Sort)的思想:每次将一个待排序的记录按其关键字大小插入到前面已经排好序的子记录中的适当位置,直到全部记录插入完成为止。 <2>常用的插入排序方法有直接插入排序和希尔排序。 (1)直接插入排序 <1>算法思路:把一个记录集(如一个数组)分成两部分,前半部分是有序区,后半部分是无序区;有序区一开始有一个元素r[0],无序区一开始是从r[1]到之后的所有元素;然后每次从无序区按顺序取一个元素r[i],拿到有序区中由后往前进行比较,每次比较时,有序区中比r[i]大的元素就往后移动一位,直到找到小于r[i]的元素,这时r[i]插到小元素的后面,则完成一趟直接插入排序。如此反复,从无序区不断取元素插入到有序区,直到无序区为空

C#插入排序算法

不羁的心 提交于 2020-03-26 19:10:35
原理: 1、第一个元素可以看做是已经排序好的小数组,第二个元素和这个小数组比较,放到合适的位置,组成新的已排序的小组数。 2、第三个元素在和前面组成的新的小数组比较,决定排在什么位置,如此循环,直到结束 public static void insertatesort() { int[] array = new int[6] { 56, 45, 85, 13, 85, 46 }; //定义一个数组 for (int i = 1; i < array.Length; i++) //外层循环,先将数组第二个元素作为基数,再将数组第三的元素作为基数 { int t = array[i]; //将一个默认的基数赋值给t,这里首先是默认下标为0的数字为基数 int j = i; //记录当前基数下标 while ((j > 0) && (array[j - 1] > t)) //判断前一个元素是否大于当前基数,如果大于则满足条件,执行循环体 { array[j] = array[j - 1];//交换顺序 如果大于的话将前一个元素放在当前基数的位置 --j; //下标前移 } //跳出循环,说明交换完成 array[j] = t; //将基数插入到下标所代表的位置 } foreach (int item in array) { Console.Write(item+" "); } } 来源:

插入排序

戏子无情 提交于 2020-03-26 08:49:56
问题描述: 通过插入排序,从小到大排序一个数组。 算法实现: public static void insertSort(int[] arr) { int insertValue; int insertIndex; for(int i = 1; i < arr.length; i++) { insertValue = arr[i]; insertIndex = i - 1; while (insertIndex >= 0 && insertValue < arr[insertIndex]) { arr[insertIndex + 1] = arr[insertIndex]; insertIndex--; } if(insertIndex + 1 != i) { arr[insertIndex + 1] = insertValue; } }} 算法解析: 1.默认数组的第一个元素有序,从第二个元素开始进行“比较-插入”操作; 2.针对待插入的值、待插入的位置设置临时变量; 3.循环遍历,将当前待插入有序数组的值,与“已经有序数组”的元素“从后往前”依次比较; 4.若待插入元素小于“已经有序数组”中的元素,则将“已经有序数组”依次向后移动,直到待插入元素不再小于有序数组中的元素; 5.一轮遍历结束后,若有数据发生移动,需要将待插入值插入到相应位置(当待插入元素不小于“已经有序数组”

八大排序算法总结

孤街浪徒 提交于 2020-03-26 05:29:24
排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。 常见的内部排序算法有:插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序等。 本文将依次介绍上述八大排序算法。 算法一:插入排序 插入排序示意图 插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。 算法步骤 : 1)将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。 2)从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。) 代码实现: void insert_sort(int array[],unsignedint n) { int i,j; int temp; for(i = 1;i < n;i++) { temp = array[i]; for(j = i;j > 0&& array[j - 1] > temp;j--) { array[j]= array[j - 1]; } array[j] = temp; } } 算法二:希尔排序 希尔排序示意图 希尔排序 ,也称

关于常见排序算法的稳定性分析和结论

落爺英雄遲暮 提交于 2020-03-26 02:57:20
这几天笔试了好几次了,连续碰到一个关于常见排序算法稳定性判别的问题,往往还是多选,对于我以及和我一样拿不准的同学可不是一个能轻易下结论的题目,当 然如果你笔试之前已经记住了数据结构书上哪些是稳定的,哪些不是稳定的,做起来应该可以轻松搞定。本文是针对老是记不住这个或者想真正明白到底为什么是稳 定或者不稳定的人准备的。 首先,排序算法的稳定性大家应该都知道,通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。 其次,说一下稳定性的好处。排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就 是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。另外,如果排序算法稳定,对基于比较的排序算法而言,元素交换 的次数可能会少一些(个人感觉,没有证实)。 回到主题,现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。 (1)冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无 聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来

八大排序算法概述

元气小坏坏 提交于 2020-03-26 01:24:33
综上,得出结论: 选择排序、快速排序、希尔排序、堆排序不是稳定的排序算法,而冒泡排序、插入排序、归并排序和基数排序是稳定的排序算法 常见排序算法的稳定性 收藏 排序算法的稳定性:若待排序的序列中,存在多个具有相同关键字的记录,经过排序, 这些记录的相对次序保持不变,则称该算法是稳定的;若经排序后,记录的相对 次序发生了改变,则称该算法是不稳定的。 稳定性的好处:排序算法如果是稳定的,那么从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用。基数排序就是这样,先按低位排序,逐次按高位排序,低位相同的元素其顺序再高位也相同时是不会改变的。另外,如果排序算法稳定,可以避免多余的比较; 回到主题,现在分析一下常见的排序算法的稳定性,每个都给出简单的理由。 (1)冒泡排序 冒泡排序就是把小的元素往前调或者把大的元素往后调。比较是相邻的两个元素比较,交换也发生在这两个元素之间。所以,如果两个元素相等,我想你是不会再无聊地把他们俩交换一下的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变,所以冒泡排序是一种稳定排序算法。 (2)选择排序 选择排序是给每个位置选择当前元素最小的,比如给第一个位置选择最小的,在剩余元素里面给第二个元素选择第二小的,依次类推,直到第n-1个元素,第n个元素不用选择了

插入排序

百般思念 提交于 2020-03-22 18:29:24
插入排序:原理就是将未排序的数据,对已经排序的数据序列从后前扫描,找到对应的位置并插入! 插入排序会涉及到两块区域:   1)有序区域:元素已经从小到大(或者从大到小)排好序了。在刚开始排序的时候有序区域为 第一个元素 ;   2) 无序区域:无序区域内的元素,元素任意分布,大开始排序之前 除了第一个元素之外的所有元素 都处于无序区域。    function insertSort(arr) { const Len = arr.length; for (let i = 1; i < Len; i++) { let j = i, temp = arr[i] // 当前检索的元素 while(j > 0 && arr[j - 1] > temp) { arr[j] = arr[j-1]; j--; } arr[j] = temp; } return arr; } 来源: https://www.cnblogs.com/garfieldzhong/p/12547308.html

Python常见的几种算法

人盡茶涼 提交于 2020-03-21 10:48:59
冒泡排序 冒泡排序 (英语:Bubble Sort)是一种简单的排序算法。它重复地遍历要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。遍历数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。 冒泡排序算法的运作如下: 比较相邻的元素。如果第一个比第二个大(升序),就交换他们两个。 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。 针对所有的元素重复以上的步骤,除了最后一个。 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 冒泡排序的分析 交换过程图示(第一次): 那么我们需要进行n-1次冒泡过程,每次对应的比较次数如下图所示: def bubble_sort(alist): for j in range(len(alist)-1,0,-1): # j表示每次遍历需要比较的次数,是逐渐减小的 for i in range(j): if alist[i] > alist[i+1]: alist[i], alist[i+1] = alist[i+1], alist[i] li = [54,26,93,17,77,31,44,55,20] bubble_sort(li) print(li) 时间复杂度