插入排序(C 语言实现)

插入排序

插入排序分为直接插入排序和折半插入排序,直接插入排序利用遍历的方式查找插入位置,时间复杂度为n^2,直接插入法由于不会改变相同元素的相对顺序,所以直接插入排序是一种稳定的排序算法。
折半插入排序(二分插入排序),折半插入利用二分法查找插入位置,只是减少了查找比较的操作,所以其时间复杂度仍为n^2,二分查找也是稳定的排序算法。

代码块

两种排序代码如下(codeblocks环境下C语言实现):

#include   
#include 
#include    //包含rand()和srand()函数

#define LIST_SIZE 100
#define MAXSIZE 10

//定义顺序表结构ADT
typedef struct
{
    int elem[LIST_SIZE];
    int length;
} SqList;

//函数声明
void InitList(SqList *List);        //列表初始化
void AcsortList(SqList *List);   //直接插入排序
void BDownsortList(SqList *List);   //折半插入排序

void main() {
    SqList seqlist;
    InitList(&seqlist);     //初始化列表

    //添加随机元素
    srand((unsigned) time(0));
    for (int i = 0; i < MAXSIZE; i++) {
        seqlist.elem[i] = rand() % 10;
        seqlist.length++;
    }
    printf("\n最初表长:%d", seqlist.length);
    printf("\n最初列表:");
    for (int i = 0; i < MAXSIZE; i++) {
        printf("%3d", seqlist.elem[i]);
    }
        AcsortList(&seqlist);   //调用直接插入排序函数
        BDownsortList(&seqlist);   //调用折半插入排序函数

}
//顺序表初始化
void InitList(SqList *List) {
    List->length = 0;
    printf("Initialize Done\n");
    printf("Afer Init length: %d\n",List->length);
}
//直接插入排序
void AcsortList(SqList *List) {
    int i,j,k,e;
    for(i=2;ilength+1;i++){  //i:[2, length],i++
        e = List->elem[i-1]; //取出基准元素
        for(j=1;j//j:[1, i-1],j++
            if(e < List->elem[j-1]){
                for (k=i-1;k>j-1;k--) //k: [i-1, j],k--
                    List->elem[k] = List->elem[k-1];    //移动元素
                List->elem[j-1] = e;
                break;    //遇到第一个大于e的元素停止比较
            }
        }
    }
    printf("\n按升序排列(直接插入排序):");
    for (int k=0;klength;k++)
        printf("%3d",List->elem[k]);
}

//折半插入排序
void BDownsortList(SqList *List){
    int i,j,e;
    int signL,signR,sign=0;

    for(i=2;i<=List->length;i++){  //i:[2, length]++
        e = List->elem[i-1];
        signL = 1;
        signR = i-1;
        while(signL <= signR){
            sign = (signL + signR)/2;
            if(e < List->elem[sign-1])
                signR = sign-1;
            else signL = sign+1;
        }
    for(j=i-1;j>=signR+1;j--)
        List->elem[j] = List->elem[j-1];
        List->elem[signL-1] = e;
        }
    printf("\n按降序排列(折半插入排序):");
    for (int k=0;klength;k++)
        printf("%3d",List->elem[k]);
}

程序运行结果如下:

程序运行结果
插入排序(C 语言实现)_第1张图片

示意图:

1、直接插入排序:
插入排序(C 语言实现)_第2张图片

算法分析:

  1. 将列表元素分成两部分[1,i-1](已完成排序)和[i,length](待排序元素);
  2. 第 i 个元素用中间变量e暂存,依次与[1,i-1]个元素进行比较;
  3. 假设 e 比[1,i-1]中的第一个元素 j 小,则需要将[j,i-1]的元素向后移动;
  4. 移动完成后将e中暂存的元素插入到第 j 个元素的位置,覆盖原数据;

2、折半插入排序:


  • 备注
    作为数据结构学习过程中笔记记录学习总结
    欢迎大家留言交流,共同学习,共同进步,谢

你可能感兴趣的:(Path,to,C)