数据结构与算法分析(C语言描述)习题2.7

问题描述:假设需要生成前N个自然数的一个随机置换。例如,{4,1,2,5,2}和{3,1,4,2,5}就是合法的置换,但{5,4,1,2,1}却不是,因为数1出现了两次而数3缺没有。这个程序常常用于模拟一些算法。我们假设存在一个随机数生成器randInt(i, j),它以相同的概率生成i和j之间的一个整数。下面是三个算法:

1.如下填入A[0]到A[N-1]的数组A;为了填入A[i],生成随机数直到它不同于已经生成的A[0],A[1], ... , A[i-1]时,再将其填入A[i]。

2.同算法1,但是要保存一个附加的数组,称之为Used(用过的)数组。当一个随机数Ran最初被放入数组A的时候,置Used[Ran]=1。这就是说,当用一个随机数填入A[i]时,可以用一步来测试是否该随机数已经被使用,而不是像第一个算法那样(可能)进行i部测试。

3.填写该数组使得A[i]=i+1。然后:

for(i = 1; i < N; i++)
    swap(&A[i], &A[randInt(0, i)]);

分别写程序执行每个算法10次,得出一个好的平均值。对N=250,500,1 000,2 000运行程序1,对N=2500,5 000,10 000,20 000,40 000,80 000运行程序2;对N=1 0000,2 0000,4 0000,8 0000,160 000,320 000,640 000运行程序3。

实现:

 1 //返回一个[i, j)内的随机数
 2 int randInt(int i, int j)
 3 {
 4     if (j - i == 0)
 5         return i;
 6     else if (j - i < 0)
 7         return 0;
 8     else
 9         return rand() % (j - i) + i;
10 }
11
12 //算法1
13 int fillArray1(int A[], int n)
14 {
15     int count, ran, k;
16
17     count = 0;
18     while (count < n)
19     {
20         ran = randInt(0, n);
21         for (k = 0; k < count; k++)
22         {
23             if (A[k] == ran)
24                 break;
25         }
26         if (k == count)
27         {
28             A[count] = ran;
29             count++;
30         }
31     }
32     return 1;
33 }
34
35 //算法2
36 int fillArray2(int A[], int n)
37 {
38     int * used, count, ran;
39
40     used = (int *)calloc(n, sizeof(int));
41     if (used == NULL)
42         return 0;
43
44     count = 0;
45     while (count < n)
46     {
47         ran = randInt(0, n);
48         if (used[ran] == 0)
49         {
50             A[count] = ran;
51             used[ran] = 1;
52             count++;
53         }
54     }
55     free(used);
56     return 1;
57 }
58
59 static void swap(int * a, int * b)
60 {
61     int temp = *a;
62     *a = *b;
63     *b = temp;
64 }
65
66 //算法3
67 int fillArray3(int A[], int n)
68 {
69     int i;
70
71     for (i = 0; i < n; i++)
72         A[i] = i + 1;
73     for (i = 0; i < n; i++)
74         swap(&A[i], &A[randInt(0, i)]);
75 }

以上算法主要有两个问题:

1). 动态数组问题:可用内存有限

算法2中要求用随机数做数组下标“Used[Ran]=1”,这就表示必须用有最大随机数个元素的变长数组Used数组。vs2013编译器不支持这种特性,我选择了动态内存分配malloc()实现Used数组。这受到了可用内存数量的限制。

2). C的随机数问题:随机数范围有限

C使用srand()和rand()产生伪随机数。我们知道,它们只能产生[0, RAND_MAX)之间的值。最多能产生(RAND_MAX+1)个不重复随机数。当N > RAND_MAX+1 时,算法不断尝试获取新的不重复随机数,陷入死循环。

如果您有更好的算法,欢迎交流。

时间: 2024-12-20 23:45:30

数据结构与算法分析(C语言描述)习题2.7的相关文章

《数据结构与算法分析—C语言描述》pdf

下载地址:网盘下载 内容简介 编辑 <数据结构与算法分析:C语言描述(原书第2版)>内容简介:书中详细介绍了当前流行的论题和新的变化,讨论了算法设计技巧,并在研究算法的性能.效率以及对运行时间分析的基础上考查了一些高级数据结构,从历史的角度和近年的进展对数据结构的活跃领域进行了简要的概括.由于<数据结构与算法分析:C语言描述(原书第2版)>选材新颖,方法实用,题例丰富,取舍得当.<数据结构与算法分析:C语言描述(原书第2版)>的目的是培养学生良好的程序设计技巧和熟练的算

数据结构与算法分析 c语言描述 pdf 高清下载

网盘下载:数据结构与算法分析 c语言描述 pdf 高清下载 – 易分享电子书PDF资源网 作者: [美] Mark Allen Weiss 出版社: 机械工业出版社 副标题: C语言描述 原作名: Data Structures and Algorithm Analysis in C:Second Edition 译者: 冯舜玺 出版年: 2004-1-1 页数: 391 定价: 35.00元 装帧: 平装 内容简介 · · · · · · 本书是<Data Structures and Alg

数据结构与算法分析_Java语言描述(第2版)pdf

下载地址:网盘下载 本书是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计). 随着计算机速度的不断增加和功能的日益强大,人们对有效编程和算法分析的要求也不断增长.本书将算法分析与最有效率的Java程序的开发有机地结合起来,深入分析每种算法,并细致讲解精心构造程序的方法,内容全面.缜密严格. 第3版的主要更新如下: ? 第4章包含AVL树删除算法的实现. ? 第5章进行了全面修订和扩充,现在包含两种较

《数据结构与算法分析Java语言描述》PDF文件免费下载

图书简介: 本书是国外数据结构与算法分析方面的经典教材,使用卓越的Java编程语言作为实现工具讨论了数据结构(组织大量数据的方法)和算法分析(对算法运行时间的估计). 随着计算机速度的不断增加和功能的日益强大,人们对有效编程和算法分析的要求也不断增长.本书把算法分析与最有效率的Java程序的开发有机地结合起来,深入分析每种算法,内容全面.缜密严格,并细致讲解精心构造程序的方法. 图书目录部分截图: 结语:总结 数据结构与算法分析需要这份PDF文档的朋友,欢迎加Q群:219571750,免费领取,

《数据结构与算法分析:C语言描述_原书第二版》CH2算法分析_课后习题_部分解答

对于一个初学者来说,作者的Solutions Manual把太多的细节留给了读者,这里尽自己的努力给出部分习题的详解: 不当之处,欢迎指正. 1.  按增长率排列下列函数:N,√2,N1.5,N2,NlogN, NloglogN,Nlog2N,Nlog(N2),2/N,2N,2N/2,37,N2logN,N3.指出哪些函数以相同的增长率增长. 答:排列如下2/N < 37 < √2 < N < NloglogN < NlogN < Nlog(N2) < Nlog2

《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

表.栈和队列是最简单和最基本的三种数据结构.基本上,每一个有意义的程序都将明晰地至少使用一种这样的数据结构,比如栈在程序中总是要间接地用到,不管你在程序中是否做了生命. 本章学习重点: 理解抽象数据类型(ADT)的概念 学习如何对表进行有效的操作 熟悉栈ADT及其在实现递归方面的应用 熟悉队列ADT及其在操作系统和算法设计中的应用 ADT 抽象数据类型(abstract data type)是一个操作的集合,是数学的抽象,在ADT中不涉及如何实现操作的集合,这可以看作是模块化设计的扩充. 对于每

数据结构与算法分析_Java语言描述(第2版)高清版pdf免费下载

下载地址:网盘下载 备用地址:网盘下载 内容简介编辑“数据结构”是计算机专业的基础与核心课程之一,Java是现今一种热门的语言.本书在编写过程中特别考虑到了面向对象程序设计(OOP)的思想与Java语言的特性.它不是从基于另一种程序设计语言的数据结构教材简单地“改编”而来的,因此在数据结构的实现上更加“地道”地运用了Java语言,并且自始至终强调以面向对象的方式来思考.分析和解决问题.本书是为数据结构入门课程(通常课号是CS-2)而编写的教材.作者Frank Carrano在编写过程自始至终特别

《数据结构与算法分析 C语言描述》读书笔记——分治算法

书中用求解最大子序列和的方式介绍了分治算法(divide-and-conquer) 分治算法是一种相对快速的算法 运行时间为O(logN) 最大子序列和的问题如下: 给出一组整数 A1  A2 … AN 求∑jk=i Ak 若所有整数均为负 则最大子序列和为0 e.g. 输入-2, 11,-4, 13, -5, -2 输出20(A2到A4) 分治算法就如同字面描述的一样 先分再治 分 指的是将问题分为两部分几乎相同的子问题 进行递归求解 治 指的是将 分 的解通过简单的手段合并 得到最终解 对于

【数据结构与算法分析——C语言描述】练习1.1——选择问题

本部分内容来自http://www.cnblogs.com/mingc,笔者在此只用于整理学习. 问题描述:编写一个程序解决选择问题.令k=N/2.画出表格显示你的程序对于N为不同值时的运行时间. 理解:设有一组N个数确定其中第k个最大者,称选择问题(selection problem) 思路:读入前k个数到临时数组tmp(并按降序排列).然后逐个读取后续数字X,当X大于第k个数时,将其加入数组tmp(并按降序排列).最后返回位置k-1上的值 #include <stdio.h> #inclu

数据结构与算法分析-c语言描述版 mark allen weiss

指出依序访问图4-61中的伸展树中关键字3,9,1,5后的结果. 图4-61 1.原理 这里主要涉及到两种旋转方式: 1)之子型旋转 2)一字型旋转 这两种方式实际有一点差别: 之子型旋转是两次单旋转的组合,而且都可以看成是将目标节点父节点的选转(后面实例进行说明) 而一字型旋转时目标节点的祖父节点的的旋转后再加上父节点的旋转(后面实例进行说明). 因此书中所指的标准AVL双旋转可以分解为两步进行. 2.习题旋转步骤: 1)3节点的访问 第一步:节点3-2-4 之字形 :父节点的旋转,因此 2-