原题链接:https://vjudge.net/problem/Aizu-ALDS1_1_A

题目描述

Write a program of the Insertion Sort algorithm which sorts a sequence A in ascending order. The algorithm should be based on the following pseudocode:

for i = 1 to A.length-1
key = A[i]
/* insert A[i] into the sorted sequence A[0,...,j-1] */
j = i - 1
while j >= 0 and A[j] > key
A[j+1] = A[j]
j--
A[j+1] = key

Note that, indices for array elements are based on 0-origin.

To illustrate the algorithms, your program should trace intermediate result for each step.

Input

The first line of the input includes an integer N, the number of elements in the sequence.

In the second line, N elements of the sequence are given separated by a single space.

Output

The output consists of N lines. Please output the intermediate sequence in a line for each step. Elements of the sequence should be separated by single space.

Constraints

1 ≤ N ≤ 100

Sample Input 1

6
5 2 4 6 1 3

Sample Output 1

5 2 4 6 1 3
2 5 4 6 1 3
2 4 5 6 1 3
2 4 5 6 1 3
1 2 4 5 6 3
1 2 3 4 5 6

Sample Input 2

3
1 2 3

Sample Output 2

1 2 3
1 2 3
1 2 3

讲解

插入排序法

  • 将开头元素视作已排序
  • 执行下述处理,直至未排序部分消失
  1. 取出未排序部分的开头元素赋给变量v。
  2. 在已排序部分,将所有比v大的元素向后移动一个单位。
  3. 将已取出的元素v插入空位。

举例说明

当对数组A = {8,3,1,5,2,1}进行从小到大的插入排序时,流程如下

0.

1.

将开头元素A[0](=8)视为已排序,所以我们取出A[1]中的3,将其插入已排序部分的恰当位置。

首先把原先位于A[0]的8移动至A[1],再把3插入A[0]。

2.

首先将比1大的A[1](=8)和A[0](=3)顺次向后移动一个位置,然后把1插入A[0]。

3.

首先将比5大的A[2](=8)向后移动一个位置,然后把5插入A[2]。

4.

首先将比5大的A[3](=8)向后移动一个位置,然后把2插入A[1]。

5.

首先将比5大的A[4](=8)向后移动一个位置,然后把1插入A[1]。

6.

排序完成。

插入排序法所需的主要变量

A[N]

长度为N的整型数组

i

循环变量,表示未排序部分的开头元素

v

临时保存A[i]值的变量

j

循环变量,用于在已排序部分寻找v的插入位置

外层循环的 i 从1开始自增。在每次循环开始时,将A[i]的值临时保存在变量v中。

接下来是内部循环:从已排序部分找出比v大的元素并让它们顺次后移一个位置。在这里,我们让 j 从 i - 1 开始向前自减,同时将比v大的元素从A[j]移动到A[j+1]。一旦j等于-1或当前A[j]小于等于v则结束循环,并将v插入当前 j+1 的位置。

程序代码及细节

#include<stdio.h>
void trace(int A[],int N){ //按顺序输出数组元素
int i;
for(i=;i<N;i++){
if(i>) printf(" "); //在相邻元素之间输出1个空格
printf("%d",A[i]);
}
printf("\n");
} void insertionSort(int A[],int N){ //插入排序(数组下标从0开始)
int j,i,v;
for(i=;i<N;i++){
v=A[i];
j=i-;
while(j>= && A[j]>v){
A[j+]=A[j];
j--;
}
A[j+]=v;
trace(A,N);
}
} int main()
{
int N,i,j;
int A[];
scanf("%d",&N);
for(i=;i<N;i++)
scanf("%d",&A[i]);
trace(A,N);
insertionSort(A,N);
return ;
}

细节关注

  • 数组长度是否足够长
  • 是否搞错了0起点和1起点的数组下标
  • 是否误用了循环变量
  • 是否输出了多余的空格或换行

总结

稳定性:在插入排序法中,我们只将比v(取出的值)大的元素向后平移,不相邻的元素不会直接交换位置,因此十分稳定

时间复杂度:最坏的情况下,每个 i 循环都需要执行 i 次移动,总共需要1 + 2 + ... + N - 1 = (N2 - N)/ 2 次移动,即算法复杂度为 O(N2

算法优势:可以快速处理相对有序的数据

Aizu_Insertion Sort的更多相关文章

  1. [算法]——归并排序(Merge Sort)

    归并排序(Merge Sort)与快速排序思想类似:将待排序数据分成两部分,继续将两个子部分进行递归的归并排序:然后将已经有序的两个子部分进行合并,最终完成排序.其时间复杂度与快速排序均为O(nlog ...

  2. [算法]——快速排序(Quick Sort)

    顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...

  3. shell之sort命令

    1 sort的工作原理 sort将文件的每一行作为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出. [rocrocket@rocrocket progr ...

  4. 详细解说 STL 排序(Sort)

    0 前言: STL,为什么你必须掌握 对于程序员来说,数据结构是必修的一门课.从查找到排序,从链表到二叉树,几乎所有的算法和原理都需要理解,理解不了也要死记硬背下来.幸运的是这些理论都已经比较成熟,算 ...

  5. SQL Tuning 基础概述06 - 表的关联方式:Nested Loops Join,Merge Sort Join & Hash Join

    nested loops join(嵌套循环)   驱动表返回几条结果集,被驱动表访问多少次,有驱动顺序,无须排序,无任何限制. 驱动表限制条件有索引,被驱动表连接条件有索引. hints:use_n ...

  6. js sort() reverse()

    数组中存在的两个方法:sort()和reverse() 直接用sort(),如下: ,,,,,,,,,,,]; console.log(array.sort());ps:[0, 1, 2, 2, 29 ...

  7. Java中的经典算法之冒泡排序(Bubble Sort)

    Java中的经典算法之冒泡排序(Bubble Sort) 神话丿小王子的博客主页 原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一 ...

  8. 2.sort 排序命令讲解

    sort命令  sort:文本排序,仅仅是对显示文件的排序,而不影响源文件的顺序,是根据ASSII码     的字符升序来排列的.        -n:安装数值大小从小到大排列 ,默认是升序.     ...

  9. 基本shell编程【3】- 常用的工具awk\sed\sort\uniq\od

    awk awk是个很好用的东西,大量使用在linux系统分析的结果展示处理上.并且可以使用管道, input | awk ''  | output 1.首先要知道形式 awk 'command' fi ...

随机推荐

  1. Linux 移动或重命名文件/目录-mv 的10个实用例子

    本文导航 -初识 mv 命令03% -1.移动文件08% -2.移动多个文件15% -3.移动目录23% -4.重命名文件或目录27% -5. 重命名目录35% -6. 打印移动信息39% -7. 使 ...

  2. mysql++ Query

    mysqlpp:: Query类存储了Connection的指针,可以用它进行SQL语句的增删改查. 连上数据库后,使用mysqlpp::Connection::query()获取Query对象 Qu ...

  3. ZendStudio在kali下无法启动

    错误如下 # # A fatal error has been detected by the Java Runtime Environment: # #  SIGSEGV (0xb) at pc=0 ...

  4. 11g等待事件之library cache: mutex X

    11g等待事件之library cache: mutex X 作者: dbafree 日期: 2012 年 07 月 01 日发表评论 (0)查看评论   library cache: mutex X ...

  5. 三者互ping,PC,虚拟机,uboot,nfs网络文件系统搭建

    要想实现三者互ping,韦老师虽然专门出了视频说明,但是在自己配置过程还是出现了问题,这里记录一下解决办法,虽然我也不知道原因,但是解决了出现的问题也实现了三者互ping. 首先,我的硬件设备是PC通 ...

  6. #pragma pack(push) 和#pragma pack(pop) 以及#pragma pack()

    我们知道结构体内存对齐字节可以通过#pragma pack(n) 的方式来指定. 但是,有没有想过一个问题,某些时候我想4字节对齐,有些时候我又想1字节或者8字节对齐,那么怎么解决这个问题呢? 此时, ...

  7. java基础篇---XML解析(二)

    XML解析之最流行的方式:DOM4J dom4j是使用java语言编写的,用于读,写,操作XML的一套组件 dom4j是一个开源的java组件,可从http://sourceforge.net/pro ...

  8. [转]获取JAVA[WEB]项目相关路径的几种方法

    http://blog.csdn.net/yaerfeng/article/details/7297479/ 在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在cl ...

  9. RabbitMQ文档翻译——Hello World!(下)

    Receiving That's it for our sender. Our receiver is pushed messages from RabbitMQ, so unlike the sen ...

  10. Linxu 学习记录

    1.配置Java人环境变量,设置后需要使用命令: source /etc/profile 让配置立即生效. # jdk7 settings JAVA_HOME=/usr/jdk1..0_79 JRE_ ...