上次朋友的一个问题,让我重新翻开了那本尘封已久的《数据结构、算法与应用》。仅仅重读了第一章,我不得不再次为专注数据结构与算法研究的科学家们佩服得五体投地。
让我佩服的问题其实很简单:生成一个list中的元素的全排列,也就是说input为:[a, b, c],output则是[abc, acb, bac, bca, cab, cba],当然list中的元素个数是不定的。是不是很简单的问题呢?不过比较愚钝的我,却没有办法想出问题的答案,尽管我知道应该使用递归来实现。
想不出来就只好看书上是怎么实现的了。基于递归的算法,通常都需要一个递归等式(recursive component,递归部分)和一个递归终结的条件(base,基本部分)。那么对于以上的问题,递归部分和基本部分都是什么呢?假设递归函数为Perm(E),E为元素的集合,那么基本部分是比较容易想到的,就是当集合E中只有一个元素的时候,Perm(E) = e,e为集合E中唯一的元素;接下来的就是递归部分了,当集合E中的元素个数大于1的时候,那么:Perm(E) = e
1.Perm(E
1)+e
2.Perm(E
2)+e
3.Perm(E
3)...+e
n.Perm(E
n),E = e
1 + E
1= e
2 + E
2 = e
3 + E
3= e
n+ E
n。也就是说,e
n.Perm(E
n)表示从集合E中取出一个元素e
n,然后将剩下的元素进行排列,两者再相连就得到了以e
n元素作为前缀的所有排列了,那么将集合E中的所有元素遍历一次,得到以每一个元素作为前缀的排列,最后就可以得到所有的排列方式了。至此,递归函数所需要的两个必要部分都清楚了,那么代码该如何实现呢?以下是书上给出的代码:
template <class T>
void Perm(T list[], int k, int m) //m为list数组index的最大值,而k则表示
position,初始值为0


{
int i;
if (k == m)

{
for (i = 0; i <= m; i++)
cout << list[i];
cout << endl;
}
else
for (i = k; i <= m; i++)

{
Swap(list[k], list[i]); //通过交换,使得每个元素都能够成为前缀
Perm(list, k+1, m); //递归调用,得到作为后缀的元素的所有排列
Swap(list[k], list[i]);
}
} Swap是一个自定义的inline函数,用作交换两个元素。尽管这样的代码很简洁,但是总觉得不是太爽了,毕竟有那么多的参数,而且似乎与算法中描述的不太像。大家再看一下python的实现:
def permute(seq):
l = len(seq)
if l == 1:
return [seq]
else:
res = []
for i in range(len(seq)):
rest = seq[:i] + seq[i+1:]
for x in permute(rest):
res.append(seq[i:i+1] + x)
return res

是不是会更为简洁,更容易理解,而且更符合算法的描述呢?在以上代码中,rest变量对应着取出元素i剩下的集合,for x in permute(rest)遍历集合rest产生的所有的排列,然后通过seq[i:i+1] + x 就可以得到以元素i作为前缀的排列了。当然这样的算法有明显的一个问题是,占用了较大的空间。因为当len(seq)>1的时候,每次函数的调用,都必须为res开辟新的空间,一旦递归嵌套的层次比较多,则需要比较大的空间了。
排列的问题解决了,接着就是组合问题(外延则是集合的子集问题)了。或许太长时间没有去思考算法与数据结构的问题了,这个问题仍然让我无从下手。对算法与数据结构有心得的朋友多多指教了。//Bow
分享到:
相关推荐
《算法与数据结构-C语言版》是针对计算机科学领域中至关重要的两个概念——算法和数据结构的深入学习资料。陈守孔版的课程通常以其详尽的解释和实用的示例而闻名,对于初学者和有经验的程序员来说都是宝贵的学习资源...
《数据结构、算法与应用——C++语言描述》是一本深入探讨计算机科学核心领域的经典教材。数据结构和算法是编程的基础,它们对于理解和优化程序性能至关重要。本书通过C++语言来阐述这些概念,使得读者能够更好地掌握...
本资料“算法-数据结构知识——树的三种不同遍历算法解析”深入探讨了树的遍历方法,这是理解和操作树型数据结构的关键技能。以下是关于树遍历的详细解释: 1. 前序遍历(Preorder Traversal): 前序遍历是一种...
算法与数据结构学习指导与习题解析——王晓东
《程序员面试代码指南——IT名企算法与数据结构题目最优解》就是这样一本专为程序员面试准备的参考书。它不仅详细介绍了面试中常见的算法和数据结构题目,而且提供了最优解的代码实现。这本书对于准备进入IT行业的...
《算法与数据结构——C语言描述(第2版)》是张乃孝先生撰写的一本经典教材,专注于讲解计算机科学中的核心概念:算法和数据结构。这本书以C语言为工具,深入浅出地阐述了各种数据结构的实现原理及其在实际问题中的...
《算法和数据结构——左程云》是一份深入探讨计算机科学核心领域的资源包,由知名专家左程云编著。这份资料集主要聚焦于算法与数据结构的学习,这对于任何计算机科学专业的学生或软件开发者来说都是必不可少的基础...
本资料集主要探讨的是“数据结构——算法设计与分析”,涵盖了多种常用的数据结构和算法设计策略,如蛮力法和贪婪法。 首先,我们来深入了解数据结构。数据结构主要包括数组、链表、栈、队列、树(二叉树、平衡树如...
数据结构与算法是计算机科学的基础,对于理解和设计高效的软件至关重要。Visual C++6.0是一种经典的集成开发环境,常用于C++编程。本教程“数据结构算法——Visual C++6.0程序集”很可能是通过C++语言来阐述数据结构...
数据结构与算法设计分析——动态规划从菜鸟到老鸟数据结构与算法设计分析——动态规划从菜鸟到老鸟数据结构与算法设计分析——动态规划从菜鸟到老鸟数据结构与算法设计分析——动态规划从菜鸟到老鸟数据结构与算法...
本资料集是基于Java语言的实现,由著名计算机科学家Mark Allen Weiss所著的《数据结构与问题求解——java语言描述》(第三版)的源码。该书通过丰富的实例和深入的理论讲解,帮助读者理解和掌握各种经典的数据结构...
《数据结构算法——Visual C++ 6.0程序集》电子教案是一个专为学习者准备的资源,它结合了理论与实践,通过Visual C++ 6.0这一经典编程环境来讲解数据结构和算法的实现。 在数据结构部分,课程可能涵盖了以下几个...
Mark Allen Weiss《数据结构与算法——C++语言描述》原书第三版,中文
《数据结构与程序设计——C++描述》是高等教育出版社出版的一本教材,由Bobert L. Kruse和Alexander J. Ryba共同编写。这本书深入探讨了如何使用C++语言进行数据结构的实现和程序设计,旨在帮助学生和程序员掌握数据...
武汉理工大学的“数据结构与算法实验——欢乐连连看”是一门将理论学习与实践应用相结合的课程,旨在帮助学生深入理解并掌握这些核心概念。在这个实验项目中,学生们通过实现一个基于经典游戏“欢乐连连看”的程序来...
对于那些希望提升自身软件开发能力的人来说,《C++语言描述——数据结构算法与应用》这本书无疑是一盏明灯,指引他们深入探索C++编程语言如何在数据结构与算法的海洋中航行。 本书不仅是数据结构教材的又一次升华,...
在这个名为“数据结构课设——教学计划编制问题”的项目中,我们将深入研究如何应用数据结构来解决实际问题,特别是与教学计划编制相关的挑战。 教学计划编制问题通常涉及合理安排课程、教师、教室资源,以满足学生...
首先,“算法和数据结构——迭代和递推(上)”这个标题提示了文档将讨论算法领域中非常核心的两个概念:迭代(Iteration)和递归(Recursion)。这两者在计算机科学中用于实现程序的重复操作和问题求解的基本方法。...
《算法与数据结构——C语言描述》是由张乃孝主编的一本教材,主要探讨如何用C语言来描述和实现算法及数据结构。该书的第一章是绪论,着重阐述学习数据结构的重要性和从问题到程序的整个过程。 学习数据结构的必要性...