排序之插入排序
插入排序:的基本思想是:每次将一个特排序的记录,按其关键字大小插入到前面已经拍好序的子文件中的适当位置,直到全部记录插入完成为止。
两种排序的算法:
直接插入排序:
希尔排序:
直接插入排序:
直接插入排序(Straight Insertion Sorting)的基本思想是:把n个待排序的元素看成为一个有序表和一个无序表,开始时有序表中只包含一个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。
改进的方法 一种查找比较操作和记录移动操作交替地进行的方法。 具体做法: 将待插入记录R[i]的关键字从右向左依次与有序区中记录R[j](j=i-1,i-2,…,1)的关键字进行比较: ① 若R[j]的关键字大于R[i]的关键字,则将R[j]后移一个位置; ②若R[j]的关键字小于或等于R[i]的关键字,则查找过程结束,j+1即为R[i]的插入位置。 关键字比R[i]的关键字大的记录均已后移,所以j+1的位置已经腾空,只要将R[i]直接插入此位置即可完成一趟直接插入排序。
一,复杂度: O(n
2)
#include <stdio.h> void InsertSort(int *a, int size) { int temp,j; for(int start=1;start<size;start++) { temp = a[start]; for(j = start;j>0&&(temp < a[j-1]);j--) { a[j] = a[j-1]; } a[j]=temp; } } void print_content(int *a, int size) { for(int i=0;i<size;i++) { printf("%d\t",a[i]); } printf("\n"); } int main(void) { int a[]={10,17,18,19,13,14,15,11,12,16,21,20,23,22}; InsertSort(a,sizeof(a)/sizeof(a[0])); print_content(a,sizeof(a)/sizeof(a[0])); return 0;}
二,排序----插入排序 插入排序的思路是:新插入的数与比它前面的数进行比较,如果新插入的数比它前面的数小,那么比它前面的数后移;否则,就找到了新插入的数的位置 插入排序的时间复杂度是:O(n^2) #include<stdio.h> #include<stdlib.h> #define N 100 int array[N]; void init_array(int a[],int n); void print_array(int a[],int n); void insert_sort(int a[],int n); int main() { init_array(array,N); insert_sort(array,N); print_array(array,N); } void init_array(int a[],int n) { int i; for(i=0;i<n;i++) a[i]=rand()%1000; } void print_array(int a[],int n) { int i; for(i=0;i<n;i++) printf("%d\n",a[i]); } void insert_sort(int a[],int n) { int i,j,temp; for(i=1;i<n;i++) { for(j=i-1,temp=a[i];j>=0&& temp<a[j]; j--) { a[j+1]=a[j]; } a[j+1]=temp; } }
2
插入排序原理:将第i个元素与前i-1个元素从右向左开始比较,若第i个元素小,则将前面的元素向后移,直到找到可以插入的位置。
比较次数为1+2+3+...+n=(1+n)*n/2,因此时间复杂度也是O(n^2)
插入排序 #include <iostream> using namespace std; //元素交换 void swap(int &a,int &b) { int temp=a; a=b; b=temp; } /*/////////////////////////////////////////////// 插入排序 */ void InsertSort(int *a,int len) { int i,j,key; for(i=1;i<len;i++) { key=a[i]; //保存a[i]的值,因为后面要修改它的值 j=i-1; while(j>=0 && a[j]>key ) { if(a[j]>key) { a[j+1]=a[j]; j--; } } a[j+1]=key; // a[j+1]=key; j++; } for(i=0;i<len;i++) cout<<a[i]<<" "; cout<<endl; } ///////////////////////////////////////////////// int main() { int n,i,a[20]; cout<<"请输入数组元素n:"<<endl; cin>>n; cout<<"请输入"<<n<<"个元素:"<<endl; for(i=0;i<n;i++) cin>>a[i]; InsertSort(a,n); return 0; }
4,
C 插入排序 插入算法描述 1.从第一个元素开始,该元素可以认为已经被排序 2.取出下一个元素,在已经排序的元素序列中从后向前扫描 3.如果该元素(已排序)大于新元素,将该元素移到下一位置 4.重复步骤3,直到找到已排序的元素小于或者等于新元素的位置 5.将新元素插入到该位置中 6.重复步骤2 示例代码 示例代码为C语言,输入参数中,需要排序的数组为arr[],排序长度为length。示例代码的函数采用in-place排序,调用完成后,arr[]中从0到length处于升序排列。 复制代码 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 char *insertion_sort_char(char arr[], int length) 5 { 6 int i; 7 for(i = 1; i < length; i ++) { 8 int key = arr[i]; 9 int j = i - 1 ; 10 while((j >= 0) && (arr[j] > key)) { 11 arr[j + 1] = arr[j]; 12 j --; 13 } 14 arr[j + 1] = key; 15 } 16 return arr; 17 } 18 19 int main() 20 { 21 char arr[] = {'a','c','p','e','q','d'}; 22 printf("%s\n", arr); 23 char *result= insertion_sort(arr, 6); 24 printf("%s\n", result); 25 exit(0); 26 } 复制代码 输出结果 gcc -o insert_sort insert_sort.c ./insert_sort acpeqd acdepq 算法分析 如果目标是把n个元素的序列升序排列,那么采用插入排序存在最好情况和最坏情况。最好情况就是,序列已经是升序排列了,在这种情况下,需要进行的比较操作需(n-1)次即可。最坏情况就是,序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。插入排序的赋值操作是比较操作的次数减去(n-1)次。平均来说插入排序算法复杂度为O(n2)。因而,插入排序不适合对于数据量比较大的排序应用。但是,如果需要排序的数据量很小,例如,量级小于千,那么插入排序还是一个不错的选择。 原理 插入排序:已知一组升序排列数据a[1]、a[2]、……a[n],一组无序数据b[1]、b[2]、……b[m],需将二者合并成一个升序数列。首先比较b[1]与a[1]的值,若b[1]大于a[1],则跳过,比较b[1]与a[2]的值,若b[1]仍然大于a[2],则继续跳过,直到b[1]小于a数组中某一数据a[x],则将a[x]~a[n]分别向后移动一位,将b[1]插入到原来a[x]的位置这就完成了b[1]的插入。b[2]~b[m]用相同方法插入。(若无数组a,可将b[1]当作n=1的数组a) 优劣 优点:稳定,快;缺点:比较次数不一定,比较次数越多,插入点后的数据移动越多,特别是当数据总量庞大的时候,但用链表可以解决这个问题。