插入排序就是将要排序的记录插入到已经排序号了的记录系列中去的过程. 插入排序是一种稳定的排序方法,时间复杂度为O(n2).
常见的插入排序算法有 直接插入排序,折半插入排序,二路插入排序,表插入排序等.
直接插入排序,折半插入排序,,表插入排序 测试通过代码如下:
// 插入排序.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
using namespace std;
void printArray(int * a,int n)
{
for(int i=0;i<n;i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
//直接插入排序
void InsertSort(int * a,int n)
{
for(int i=1;i<n;i++)
{
int value=a[i];
int j=i-1;
for(;j>=0 && value<a[j];j--)
{
a[j+1]=a[j];//后移
}
a[j+1]=value;
}
}
//折半插入排序
void BInsertSort(int * a,int n)
{
for(int i=1;i<n;i++)
{
int low=0,high=i-1;
//寻找插入位置
while(low<=high)
{
int mid=low+(high-low)/2; //low=(high+low)/2
if(a[i]<a[mid])
high=mid-1;
else
low=low+1;
}
//插入位置在low处,及high+1处
//后移操作
int temp=a[i];
for(int j=i-1;j>=low;j--)
{
a[j+1]=a[j];
}
a[low]=temp;
}
}
const int size=20;
//表插入排序
typedef int key;
typedef struct Node
{
key value;//记录关键字
int next;//记录比它大的记录所在位置
}Node;
typedef struct
{
Node r[size];//记录表
int length;//记录表长度
int minIndex;//记录最小的记录所在小标
}SLinkListType;
//求得一个有序链表
void SLLInsertSort(SLinkListType &SL)
{
if(SL.length<1)
return;
SL.r[0].next=-1;//-1表示没有后续
SL.minIndex=0;
for(int i=1;i<SL.length;i++)
{
if(SL.r[i].value<SL.r[SL.minIndex].value)
{
SL.r[i].next=SL.minIndex;
SL.minIndex=i;
}
else
{
int pre=SL.minIndex;
int p=SL.r[SL.minIndex].next;
while(p!=-1 && SL.r[i].value>=SL.r[p].value)
{
pre=p;
p=SL.r[p].next;
}
//第i个记录插入在pre和p之间
SL.r[pre].next=i;
SL.r[i].next=p;
}
}
}
//输出表插入排序得到的结果
void printInsResult(SLinkListType SL)
{
int p=SL.minIndex;
while (p!=-1)
{
cout<<SL.r[p].value<<" ";
p=SL.r[p].next;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
int a[]={49,38,65,97,76,13,27,49};
int n=sizeof(a)/sizeof(int);
printArray(a,n);
//直接插入排序
//InsertSort(a,n);
//折半插入排序
//BInsertSort(a,n);
//表插入排序
SLinkListType SL;
for(int i=0;i<n;i++)
{
SL.r[i].value=a[i];
}
SL.length=n;
SLLInsertSort(SL);
printInsResult(SL);
//printArray(a,n);
system("PAUSE");
return 0;
}
参考书籍:数据结构(C语言版 严蔚敏) 插入排序章节