博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
算法导论第二章 习题作业记录
阅读量:6546 次
发布时间:2019-06-24

本文共 4754 字,大约阅读时间需要 15 分钟。

 

 

本系列使用CLRS算法导论第二版。

 讨论QQ群181539446 加群请写明来自博客园

 

2.1算法入门

1. Exercises 2.1-1

给出A=<31,41,59,26,41,58>插入排序的实际执行过程

31,41,59,26,41,58

1 31

2 31,41

3 31,41,59

4 26,31,41,59,

5 26,31,41,58,59

2.Exercises 2.1-2

改成降序

INSERTION-SORT-DESC(A)

31,41,59,26,41,58

1 for j ← 2 to length[A] //从第2个开始往后遍历

2  do key ← A[j] //Aj 待插入的元素

3  ▹ Insert A[j] into the sorted sequence A[1 j - 1].

4 i ← j - 1

5  while i > 0 and A[i] < key

6  do A[i + 1] ← A[i]

7  i ← i - 1

8  A[i + 1] ← key

Exercises 2.1-3

Consider the searching problem:

• Input: A sequence of n numbers A = a1, a2, . . . , an and a value v.

• Output: An index i such that v = A[i] or the special value NIL if v does not appear in

A.

Write pseudocode for linear search, which scans through the sequence, looking for v. Using a

loop invariant, prove that your algorithm is correct. Make sure that your loop invariant fulfills

the three necessary properties.’

For (i=0 to length[A])

{

If( A[i]==v )

Return i

}

Return nil;

Exercises 2.1-4

Consider the problem of adding two n-bit binary integers, stored in two n-element arrays A

and B. The sum of the two integers should be stored in binary form in an (n + 1)-element

array C. State the problem formally and write pseudocode for adding the two integers.

1 形式化描述:

画表格

2 伪代码

Int j=0;  //表示进位

For i to n{

If (A[i]+B[i]+j>=2){

C[i]=A[i]+B[i]+j-2;

J=1;

}Else{

J=0;

C[i]=A[i]+B[i]+j;

}

}

C[n+1]=j;

官方答案

2.2算法分析

1.

N^3

2.选择排序

void SelectionSort(int A[],int length){

int index=0;

int temp=0;

int i,j;

for ( j=0;j<length-1;j++){//外层遍历           n

index=j;

for (i=j+1;i<length;i++){//内层逐个比较找出最小者的下标       n(n-1)

if(A[i]<A[index]){      //如果某项比该项小                n(n-1)*(1)

                 index=i;      //则将某项与其他项比                   n(n-1)*(1)

            }

        }

//交换第index个和第j个

        temp=A[j];A[j]=A[index];A[index]=temp;

    }

for ( j=0;j<length;j++){//测试

     printf(" %d ",A[j]);

    }

}

3.

平均情况为n/2 最坏情况为n。

4.

检查输入是否符合特定的匹配条件,然后直接给出预先计算的答案。

如 2^16 =655536

2.3算法设计

1.合并排序的过程

3, 41,52, 26, 38, 57, 9, 49

3, 41,52, 26, 38, 57, 9, 49

3, 41,26, 52, 38, 57, 9, 49

3, 26,41, 52,  9,38, 49, 57

3, 9,26,38, 41, 49, 52,57

2.改写merge_sort

//=================================

///A[...p..q,q+1...r...]

#define  N1 3

#define  N2 3

// ---------------------------------------------------------------------------------------------------------

// Description: Merge_sort(2.3-2)

// Input:

// Output:

// Return:

// Exception:

// ---------------------------------------------------------------------------------------------------------

void Merge_sort(int A[],int p,int q,int r){

// int n1=q-p+1;

// int n2=r-q;

int L[N1];

int R[N2];

int i,j=0;

//复制数组

for(i=0;i<N1;i++){

L[i]=A[p+i];

}

for(j=0;j<N2;j++){

R[j]=A[q+j+1];

}

i=0,j=0;

int end,n=0;

//依次取出L、R的头个元素比较并复制到A中

for(int k=p;k<r+1;k++){

if(L[i]<R[j]){

A[k]=L[i];i++;

}else{

A[k]=R[j];j++;

}

//判断是否达到边界

if(i==N1+1){

for(;j<N2;j++,k++){

A[k]=R[j];

}

break;

}else if(j==N2+1){

for(;i<N1;i++,k++){

A[k]=L[i];

}

break;

}

}

//测试

for ( int z=p ;z<r+1;z++){//外层遍历

     printf(" %d ",A[z]);

    }

}

3.略

4.略

5.二分查找,直接上THE C PROGRAM上的

注:我在重写的时候使用了

High=n+1;

Mid=(high+low+1)/2;

这样的话,无法退出,因为这里的+1将导致最后low<=high永远成立。

/* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */

int binsearch(int x, int v[], int n)

{

int low, high, mid;

low = 0;

high = n - 1;

while (low <= high) {

mid = (low+high)/2;

if (x < v[mid])

high = mid - 1;//

else if (x > v[mid])

low = mid + 1;

else /* found match */

return mid;

}

return -1; /* no match */

}

6.

查找可以改成lgN,但移动仍然需要O(N)。

当然如果改成链式存储结构,就没有移动的问题。那么时间复杂度可以降低。

7

此题零零散散耗费了我一些时间,一开始我就想到了使用nlgn 的排序排好,但是一直没想到合适的比较方法。

最开始我想通过排除一些情况,如将数组分成两半,其中后半部分为>x的数,但是这样仍然不能解决问题(N任选2),而且可能出现负数。

也许是在做此题前,刚做了二分查找,也许是二分查找定位刚好是lgn的复杂度,再配合一次遍历耗时n,我想到了下面的方法,后来发现官方答案也是如此。

1使用归并排序

2 遍历i to n,定位另一个数使用二分查找。

思考题

1.

1)因为对于1个长为k的待排序的数组,其时间复杂度为o(k^2),因为有n/k个,相乘得nk

2)参考图2-5,每层共需要n个操作,共lg(n/k)层。相乘得nlg(n/k)

3)(未理解)

The modiÞed algorithm has the same asymptotic running time as standard

merge sort when (nk +n lg(n/k)) = (n lg n). The largest asymptotic value

of k as a function of n that satisÞes this condition is k = (lg n).

To see why, Þrst observe that k cannot be more than (lg n) (i.e., it can’t have

a higher-order term than lg n), for otherwise the left-hand expression wouldn’t

be (n lg n) (because it would have a higher-order term than n lg n). So all

we need to do is verify that k = (lg n) works, which we can do by plugging

k = lg n into (nk + n lg(n/k)) = (nk + n lg n − n lg k) to get

(n lg n + n lg n − n lg lg n) = (2n lg n − n lg lg n) ,

which, by taking just the high-order term and ignoring the constant coefÞcient,

equals (n lg n).

4)(未理解)

In practice, k should be the largest list length on which insertion sort is faster

than merge sort.

2.冒泡排序

官方答案为

我的疑问是:在最坏情况下,二层循环后,还有2次操作,也就是说,最坏情况应该是n^2-n

3.霍纳规则 第三问没看明白。

4.

1) 2-3     2-8     2-6 3-8  3-6

2)逆序的最多 例如  5,4,3,2,1, 共 4+3+2+1即 n个中有(1+n-1)(n-1)/2=n(n-1)/2

3)逆序对的个数即 “额外”操作,实际执行次数=最好情况+逆序对个数。

4)将合并排序的改序步骤变为统计即可。

转载地址:http://pmedo.baihongyu.com/

你可能感兴趣的文章
WSDP
查看>>
Memory Management
查看>>
The Packaging Process in Yocto/OE
查看>>
JQUERY 对 表格中的数据重排序
查看>>
程序员常用借口指南
查看>>
关于PXE网络安装linux系统中碰到的个别问题
查看>>
awk 常用方法
查看>>
Android网络框架实现之【Retrofit+RxJava】
查看>>
Android文件的加密与解密
查看>>
【原】记录一句话
查看>>
Android标题栏,状态栏
查看>>
java笔记:SpringSecurity应用(二)
查看>>
php记录代码执行时间
查看>>
简简单单几段代码让自己变成最合格的网站管理员
查看>>
Slim Text 0.0.9 发布, 代码开源!
查看>>
[置顶] 遵循Java EE标准体系的开源GIS服务平台之二:平台部署
查看>>
shell语法简单介绍
查看>>
Java递归算法——阶乘
查看>>
Multi-voltage和power gating的实现
查看>>
JavaScript面向对象 ~ 原型和继承(1)
查看>>