书中第一个讲到的排序算法:
插入排序:对输入序列A,进行从小到大排序
A:表示输入的序列;
len(A):表示输入序列的长度
insert-sort(A)
{
for j ←2 to len[A]
do key ←A[j]
i ← j-1
while i >0 and A[i] > key
A[i+1] ← A[i]
i ← i - 1
A[i+1]←key
}
//数组内容从1开始 从小到大排序
void insert_srot(int *A, int len)
{
int i, j, key;
if (NULL == A)
{
return;
}
for (j =2; j <= len; ++j)
{
i = j - 1;
key = A[j];
while(i > 0 && key < A[i])
{
A[i + 1] = A[i];
--i;
}
A[i + 1] = key;
}
}
个人的看法:
1)在选择插入位置的时候,从右向左遍历;
2)关键还是算法正确性的证明,而且很多时候会用到数学归纳法;(这是日常工作中常常忽视的问题~~)
习题2.1-2重写过程insert-sort,使之按非升序排序
insert-srot(A)
{
for j ← 2 to len[A]
j ←j - 1
key ←A[j]
while i > 0 and key > A[i]
A[i+1] ← A[i]
i ← i -1
A[i+1] ← key
}
习题2.1-3线性查找一个数
find(A, v)
{
for j ←1 to len[A]
if(v == A[j])
return j
return NIL
}
习题2.1-4求数组
一、
//c = a + b
//a和b的len为n
//c的len为n+1
//都是从第一位开始
//数组中从左到右存的是低位到高位
getBinSum(a,b, n,c)
{
carry ←0
for i ←1 to length[a]
{
tmp ← a[i]+b[i]+carry
c[i] = tmp % 2
if tmp > 1
then carry ← 1
}
c[i+1] ← carry
}
二、
//c = a + b
//a和b的len为n
//c的len为n+1
//都是从第一位开始
//数组中从左到右存的是高位到低位
getBinSum(a,b, n,c)
{
carry ←0
for i ← length[a] to 1
{
tmp ← a[i]+b[i]+carry
c[i + 1] = tmp % 2
if tmp > 1
then carry ← 1
else
carry ←0
}
c[0] ← carry
}
2.2-1 O(n³)
2.2-2
select-sort(A)
{
for i←1 to length[A]-1
min←i
for j←i+1 to length[A]
if A[j] < A[min]
min ←j
A[i]↔A[min]
}
//数组内容从1开始 从小到大排序
void select_sort(int *A, int len)
{
int i, j, min;
int tmp;
for(i=1; i < len; ++i)
{
min = i;
for(j = i + 1; j <=len; ++j)
{
if(A[min] > A[j])
{
min = j;
}
}
tmp = A[i];
A[i] = A[min];
A[min] = tmp;
}
}
问1:这个算法的循环不变式是什么?
第一次将最小的元素放在第一个位置,然后循环找寻剩下的n-1个元素中的最小的放入第2个位置,如此的保持。
问2:为什么他仅仅需要在头n-1个元素上运行,而不是在所有的n个元素上运行?
因为在对选择往n-1这个位置上放元素的时候,需要比较剩下的这两个元素的大小,那么选择最小的放在n-1这个位置,那么最后剩下的那个元素当然就是最大的元素了。因此不用再计算了。
问3:以O的形式写出选择排序的最佳情况和最坏情况下的运行时间?
select-sort(A)
{
1: for i←1 to length[A]-1
2: min←i
3: for j←i+1 to length[A]
4: if A[j] < A[min]
5: min ←j
6: A[i]↔A[min]
}:
cost times
1: c1 n
2: c2 n-1
3: c3 n-1次T[j]
4: c4 n-1次T[j]-1
5: c5 n-1次T1[j]
6: c6 n-1次
T[j] = n
T总=c1*n + c2 *(n-1) + c3 * (n+2)*(n-1)/2 + c4 * n* (n-1)/2 +c5*(n-1)T1[j] + c6 * n-1
最坏情况:T1[j] = n-1 则c5*(n-1)T1[j] = c5 * n * (n-1)/2
最好情况:T1[j] = 0 则c5*(n-1)T1[j]=0
因此最好和最好情况都是O(n²)
2.2-3
平均是:检查输入的一半;(一半怎么证明仍需要考虑??)
最好是:检查所有的元素一遍;
2.2-4 以最好的情况对算法作为输入,就能够使得算法最好的运行时间