Insertion Sort
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
分析
本题就是实现基本的数组的插入排序,考察的将伪代码实现的能力
代码
#pragma warning(disable:4996)
#include<iostream>
#include<stdio.h>
using namespace std;
int main(){
int n;//数组长度
cin >> n;
int N[105];
for (int i = 0; i < n; i++) {
cin>> N[i];
}
for (int i = 0; i < n; i++) {
cout << N[i];
if (i != n - 1) {
cout << " ";
}
else {
cout << endl;
}
}//输出数组,之间空格,行末换行
//cout << endl;
for (int i = 1; i < n; i++) {
int temp = N[i];//用来记录要插入的这个元素
int temp2=-1;//用来标记是否移动
for (int j = i-1; j >= 0; j--) {
//if (N[i] < N[j]) {
if(temp < N[j]) {//若要插入的小于当前元素,则当前元素后移一位,知道找到合适的位置插入
N[j + 1] = N[j];
temp2 = j;//若发生移动改变标记位,记录要移动的位置
}
}
if (temp2 != -1) {
N[temp2] = temp;//将其插入
}//插入排序
for (int i = 0; i < n; i++) {
cout << N[i];
if (i != n - 1) {
cout << ' ';
}
}
cout << endl;
}
system("pause");
return 0;
}
思路
简单的选择排序,主要包括三个部分,读入数组,插入排序,每趟排序后输出数组,思路没有难度,主要是一些细节的处理,首先输出数组需要判断输出空格话说换行,插入排序时候,需要一个变量来记录最后要插入的位置,一个变量来记录要插入的元素,开始写代码时,我没有将这个要插入的元素保存,而是直接用N[i],而之后的操作中,N[j+1] = N[j]则会覆盖掉N[i]的元素,导致排序错误,对于可能会被覆盖掉的元素,需要用一个变量存一下
要点
- 思路是每次将i插入使前i个元素有序,一个元素必定有序,所有i从第二个元素开始遍历
- j因为要给i插空,所以应该从后往前遍历,如果从前往后遍历,N[j+1]=N[j]就会覆盖需要的元素,导致出错
书上的代码
#pragma warning(disable:4996)
#include<stdio.h>
void trace(int A[], int N) {
for (int i = 0; i < N; i++) {
if (i != 0) {
printf(" ");
}
printf("%d", A[i]);
}
printf("\n");
}
void insertionSort(int A[], int N) {
int j, i, v;
for (int i = 1; i < N; i++) {
v = A[i];
j = i -1;
while (j >= 0 && A[j] > v) {
A[j + 1] = A[j];
j--;
}
A[j + 1] = v;
trace(A,N);
}
}
int main() {
int N, i, j;
int A[100];
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &A[i]);
}
trace(A, N);
insertionSort(A, N);
return 0;
}
要点
- 将遍历数组,插入排序封装为函数,复用性更好