直接插入排序

直接插入排序的基本操作是将一个记录插入到已经排序好的有序表中(最开始假设第一个数为已排序),从而得到一个新的、记录数增1的有序表。

稳定性:直接插入排序是稳定排序

复杂度:  最好: O(n)  最差: O(n^2)  平均: O(n^2)

辅助空间:O(1)

 

下面是根据书上用L[0]存储哨兵位置而写的直接插入排序,由于书是对于顺序表进行排序,而我此处仅仅是数组,且要传参数n,故给定n值只能排序数组的后n-1个数(即序号为1~n-1的数)。 给定代码是为了和下面的对n个数的排序进行一个对照而已。

/* 直接插入排序更适合从1开始的数组(或者说下面这个程序0位置必须不用于存储数据)*/
/* n传值n但只能排序后n-1个数*/
void InsertSort1(int *L, int n){
    int i, j;
    for (i = 1; i < n - 1; ++i){
        //i表示已经有序的序列的最后一个下标
        if (L[i + 1] < L[i]){
            //已经有序序列的下一位找到更小的,需要插入
            L[0] = L[i + 1]; //设置哨兵,正是由于这里用到了L[0]
            for (j = i; L[j] > L[0]; --j){
                L[j + 1] = L[j]; //比哨兵值大的都往后移(或者这一直移动到L[0])
            }
            //此时j的数小于哨兵或j位于L[0]
            L[j + 1] = L[0]; //哨兵插入正确位置
        }//if
    }//for(i)
}
View Code

接下来是自己写的给定数组和元素个数n,对n个数进行排序的数组实现,可用于和上面对照。

/*直接插入排序 --- 数组法(且给定n就排序n个数)*/
void InsertSort2(int *L, int n){
    int i, j, tmp;
    for (i = 0; i < n - 1; ++i){
        //i为已排序序列的最大值下标
        if (L[i + 1] < L[i]){
            //后面的数小于已排序的序列,需要插入
            tmp = L[i + 1]; //设置哨兵值
            //利用&&运算符的短路特性可防止数组越界(即避免访问L[-1])
            for (j = i; j >= 0 && L[j] > tmp; --j){
                L[j + 1] = L[j];
            }//for(j)
            //结束后j为-1或比哨兵值小地数的位置
            L[j + 1] = tmp;
        }
    }//for(i)
}
View Code

加下来是直接插入排序的指针实现:

/* 直接插入排序 --- 指针实现 */
/* [head,tail)为左闭右开区间 */
void InsertSort(int* head, int* tail){
    int *p, *q, tmp;
    for (p = head; p < tail - 1; ++p){
        if (*(p + 1) < *p){
            tmp = *(p+1); //设置哨兵值
            for (q = p; q >= head && *q > tmp; --q){
                *(q + 1) = *q;
            }
            //此后q在head的前一位后者在第一个小于哨兵值的位置
            *(q + 1) = tmp;
        }
    }
}
View Code

 

转载于:https://www.cnblogs.com/tommychok/p/5031669.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值