直接插入排序:
直接插入排序的基本操作是将一个记录插入到已经排好序的有序表中,从而得到一个新的、记录数增1的有序表。
主要思想:
后一个数如果比前一个数小的话,需要往前插入,然后用第一个下标的数据作为哨兵作为下面循环的判断条件
代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<ctime>
#define MAXSIZE 10
#define OK 1
#define TRUE 1
#define FLASE 0
typedef int Status;
typedef struct
{
int r[MAXSIZE]; //用于存储要排序数组
int length; //用于记录顺序表的长度
}SqList;
Status initializer_list(SqList *L){
L->length=0;
return OK;
}
//i为插入位置,e为插入的值
Status Insert_List(SqList *L,int i,int e){
int k;
if(L->length==MAXSIZE)
return FLASE;
if(i<1||i>L->length+1)
return FLASE;
if(i<=L->length){ //插入位置不在尾部
//需要把第i个位置的数据全部往后移动
for(k=L->length;k>=i;k--)
L->r[k]=L->r[k-1];
}
L->r[i-1]=e;
L->length++;
return OK;
}
Status visit(int s){
printf("%d ",s);
return OK;
}
//打印每个顺序表的元素
Status List_Traverse(SqList L)
{
for(int i=0;i<L.length;i++)
visit(L.r[i]);
printf("\n");
return OK;
}
Status List_length(SqList L)
{
return L.length;
}
//交换L中数组r的下标为i和j的值
void swap(SqList *L,int i,int j)
{
int temp=L->r[i];
L->r[i]=L->r[j];
L->r[j]=temp;
}
//测试数据是0 5 3 4 6 2
void InsertSort(SqList *L)
{
int i,j;
for(i=2;i<L->length;i++){
if(L->r[i]<L->r[i-1]){ //后一个数据小于前一个需要往前插入
L->r[0]=L->r[i]; //作为下面循环的终止条件
for(j=i-1;L->r[j]>L->r[0];j--){ //大于当前数据的都需要往后移动
L->r[j+1]=L->r[j];
}
L->r[j+1]=L->r[0];
}
}
}
int main(){
int len;
SqList L;
initializer_list(&L);
Insert_List(&L,1,2);
Insert_List(&L,1,6);
Insert_List(&L,1,4);
Insert_List(&L,1,3);
Insert_List(&L,1,5);
Insert_List(&L,1,0);
len=List_length(L);
printf("线性表的长度为=%d\n",len);
//查看线性表的元素
printf("线性表中的数据是:");
List_Traverse(L);
InsertSort(&L);
printf("线性表中的数据排序后是:");
List_Traverse(L);
}
复杂度分析:
从空间上看,我们需要一个记录的辅助空间,所以我们主要看它的时间复杂度。
最好的情况,就是排序的表示有序的,需要比较n-1次,没有移动的记录,时间复杂度为O(n)
最坏的情况,排序表是逆序额,需要比较2+3+...+n=(n+2)*(n+1)/2,移动的次数也是n^2次的
所以我们得出直接插入排序法的时间复杂的为O(n^2)