算法导论学习笔记:2.1-插入排序

不假思索的写出这样的代码:

/*N:数组长度*/
for (i = 1; i < N; i++){
    int t = i;
    while (t > 0?a[t]<a[t-1]:0){
        int k = a[t];
        a[t] = a[t - 1];
        a[t - 1] = k;
        t = t - 1;
    }
}

不停与前一个元素比较,如果顺序不对那么交换;如果顺序对了,那么原a[i]里的元素已经找到了位置。a[0..i-1]的元素都是有序的,也就是书中所谓的“循环不变式”。

  另:while循环中的表达式能不能写成“t > 0 && a[t] < a[t-1]”?似乎有可能出现访问越界?还请指点迷津。

而根据书上给出的伪代码写出来则是:

for (i = 1; i < N; i++){
    int t = a[i], j = i - 1;
    while (j >= 0 && a[j] > t){
        a[j + 1] = a[j];
        j--;
    }
    a[j + 1] = t;
}

没有明显的交换,实际上和“找出a[i]应在的位置a[k],将a[k+1..i-1]的元素后移一位”是相同的原理,但是书中这样写明显简洁了很多。

时间: 2024-10-18 23:41:52

算法导论学习笔记:2.1-插入排序的相关文章

【算法导论学习笔记】第3章:函数的增长

????原创博客,转载请注明:http://www.cnblogs.com/wuwenyan/ ? 当算法的输入n非常大的时候,对于算法复杂度的分析就显得尤为重要,虽然有时我们能通过一定的方法得到较为精确的运行时间,但是很多时候,或者说绝大多数时候,我们并不值得去花精力求得多余的精度,因为精确运行时间中的倍增常量和低阶项已经被输入规模本身的影响所支配.我们需要关心的是输入规模无限增加,在极限中,运行时间是如何随着输入规模增大而增加的,通常来说,在极限情况下渐进地更优的算法在除很小的输入外的所有情

算法导论学习笔记 -(1)

一个ACM若菜,趁着ACM淡季,开始学习算法导论了,经过一年的ACM学习,逐渐的发现,学东西,深入才是王道,以前学习一个算法,总是看懂了就开始做题,到后来才发现很多题目,会算法,却不知道是用这个算法,这就是算法理解的不到位的后果,从今天开始,定下目标: 1.深入系统的学习算法, 2.学会纸上写伪代码,每章的代码自己先在纸上写一遍, 3.每节的学习笔记和算法都要写在博客上. 在博客上记录自己的学习笔记,方便以后温习.   欢迎各路大神路过指正错误之处. 现在,先写写书上的第一个算法,插入排序. 算

算法导论学习笔记 (页码:9 ~ 16)

前面算法在生活中不谈,算法的重要性不谈,直接说算法. 第2章 算法基础 2.1 插入排序 书中主要介绍了插入排序的思想,即对于数组A[0 ~ N - 1],长度为N.那么,升序的插入排序的过程即是从A[1]开始,先和A[0]比较,如果比A[0]小,那么将A[0]的元素顺序后移放置在A[1]中,将原本A[1]的元素插入在A[0]的位置上,同理再拿A[5]举例,如果比A[4]小,那么A[4]后移,继续比较A[3],如果还是小,A[3]后移,直到找到合适的位置进行插入,原书中提供的伪代码,我这里提供对

算法导论学习笔记(2)-归并排序

今天学习了算法导论上的归并排序算法,并且完成了在纸上写出伪代码,以前就学过归并但是理解的不够透彻,以 前还一直困惑:为什么明明归并排序比快排的时间复杂度更稳定,为什么库函数不用归并而用快排,现在知道原因了,因为归并排序必须开额外的空间,而且空间开销还比较大,下面介绍算法: 首先,归并排序用到了分治的思想,把大数据分成若干个小数据,然后再分别对小数据进行处理,最后把小数据 合并成大数据. 其次,归并排序用到了一个最重要的特点,就是把两组已经排序的数据合并成一组有序数据,并且该过程的时间复 杂度为O

算法导论学习笔记(3)-习题2.3-7-排序+二分

question(题意): Describe a O(n lg(n))-time algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x. 设计一个O(n lg(n))时间复杂度的算法,给定一个n个数字的集合,和一个数字x, 问,是否能在这个集合中找到两个数字,他

算法导论学习笔记(1)----插入排序

//升序排列#include <iostream> using namespace std; int main() { int a[5]={1,5,2,3,4}; for (int i=1;i<5;i++) { int key=a[i]; int j=i-1; while(j>=0&&a[j]>key) { a[j+1]=a[j]; j--; } a[j+1]=key; } for (int i=0;i<5;i++) { cout<<a[i]

算法导论学习笔记 第7章 快速排序

对于包含n个数的输入数组来说,快速排序是一种时间复杂度为O(n^2)的排序算法.虽然最环情况的复杂度高,但是快速排序通常是实际应用排序中最好的选择,因为快排的平均性能非常好:它的期望复杂度是O(nlgn),而且O(nlgn)中的常数因子非常小.另外,快速排序还可以实现原址排序,甚至在虚拟环境中也能很好的工作. 1 快速排序的描述 与归并排序一样,快速排序也使用了分治法的思想,下面是对一个典型的子数组A[p.. r]进行快速排序的分治过长: 分解:数组A[p.. r]被划分为两个(可能为空)子数组

算法导论学习笔记——第12章 二叉查找树

二叉查找树性质 设x是二叉查找树中的一个结点,如果y是x的左子树中的一个结点,则k[y]<=key[x]:如果y是右子树中的一个结点,则k[y]>=k[x] 1 //中序遍历算法,输出二叉查找树T中的全部元素 2 INORDER-TREE-WALK(x) 3 if x!=nil 4 then INORDER-TREE-WALK(left[x]) 5 print key[x] 6 INORDER-TREE-WALK(right[x]) 查找 1 //递归版本 2 TREE-SEARCH(x,k)

算法导论学习笔记——第1章

所谓算法,就是定义良好的计算过程,它取一个或一组值作为输入,并产生出一个或一组值作为输出.亦即,算法是一系列的计算过程,将输入值转换成输出值. 一些常见的算法运行时间量级比较:对数级<多项式级<指数级<阶乘级 1 lgn < n 1/2 < n < nlgn < n 2 < n 3 < 2 n < n!

算法导论学习笔记1---排序算法(平台:gcc 4.6.7)

平台:Ubuntu 12.04/gcc 4.6.7 插入排序 1 #include<vector> 2 #include <algorithm> 3 #include<iostream> 4 using namespace std; 5 6 template <typename T> 7 void insertSort(vector<T>& vec){ 8 //vector<T>::iterator ite; 9 for(au