- 5
- 0
- 约8.76千字
- 约 11页
- 2017-02-01 发布于北京
- 举报
回溯算法
引言
算法思想????? 回溯(backtracking)是一种系统地搜索问题解答的方法。为了实现回溯,首先需要为问题定义一个解空间(solution space),这个空间必须至少包含问题的一个解(可能是最优的)。???? 下一步是组织解空间以便它能被容易地搜索。典型的组织方法是图(迷宫问题)或树(N皇后问题)。????? 一旦定义了解空间的组织方法,这个空间即可按深度优先的方法从开始节点进行搜索。
回溯方法的步骤如下:???? 1) 定义一个解空间,它包含问题的解。?????2) 用适于搜索的方式组织该空间。???? 3) 用深度优先法搜索该空间,利用限界函数避免移动到不可能产生解的子空间。回溯算法的一个有趣的特性是在搜索执行的同时产生解空间。在搜索期间的任何时刻,仅保留从开始节点到当前节点的路径。因此,回溯算法的空间需求为O(从开始节点起最长路径的长度)。这个特性非常重要,因为解空间的大小通常是最长路径长度的指数或阶乘。所以如果要存储全部解空间的话,再多的空间也不够用。
算法应用回溯算法的求解过程实质上是一个先序遍历一棵状态树的过程,只是这棵树不是遍历前预先建立的,而是隐含在遍历过程中数据结构(严蔚敏).
(1) 幂集问题(组合问题) (参见《数据结构》(严蔚敏))???? 求含N个元素的集合的幂集。???? 如对于集合A={1,2,3},则A的幂集为???? p(A)={{1,2,3},{1,2},{1,3},{1},{2,3},{2},{3},Φ}幂集的每个元素是一个集合,它或是空集,或含集合A中的一个元素,或含A中的两个元素,或者等于集合A。反之,集合A中的每一个元素,它只有两种状态:属于幂集的元素集,或不属于幂集元素集。则求幂集P(A)的元素的过程可看成是依次对集合A中元素进行“取”或“舍”的过程,并且可以用一棵状态树来表示。求幂集元素的过程即为先序遍历这棵状态树的过程。下面给出程序:
#include?stdio.h#include?malloc.hr#define燛RROR?c.#define燨K?R?typedef爄nt燛lemType;actypedef爏truct燣Nodea{牋牋ElemType燿ata;de牋牋struct燣Node?next;acki}燣Node,*LinkList;;//初始化LinkList?ListInit(){牋牋LNode?base=(LinkList)malloc(sizeof(LNode));现回溯牋牋base-data=0;nk牋牋base-next=NULL;is牋牋return燽ase;ULL}//插入一个元素int?ListInsert(LinkList?L,int?i,ElemType?e){牋牋LNode?p,*s;(Li牋牋int爅=0;*s;牋牋p=(LNode?)L;Lin牋牋while(pji-1)kL牋牋wh{牋牋牋牋p=p-next;1)k牋牋牋牋++j;next牋牋}++牋牋if(!p||ji-1))牋牋牋牋return燛RROR;kLis牋牋s=(LNode?)malloc(sizeof(LNode));mTy牋牋s-data=e;al牋牋s-next=p-next;si牋牋p-next=s;ne牋牋return燨K;ne}//删除一个结点int?ListDelete(LinkList?L,int?i,ElemType?e){牋牋LinkList爌=L,q;nkL牋牋int爅=0;爌=L牋牋while(p-nextji-1)L牋牋wh{牋牋牋牋p=p-next;j牋牋牋牋++j;next牋牋}++牋牋if(!(p-next)||ji-1)L牋牋牋牋return燛RROR;ji-1牋牋q=p-next;OR牋牋p-next=q-next;i-牋牋e=q-data;ne牋牋free(q);;}//长度int?ListLength(LinkList燣),{牋牋LinkList爌=L;Lin牋牋int爅=0;爌=L牋牋if(!L)爌牋牋牋牋return燛RROR;nkLis牋牋while(p-next)nk牋牋wh{牋牋牋牋p=p-next;)nk牋牋牋牋++j;next牋牋}++牋牋return爅;xt;}//查找一个元素int?GetElem(LinkList?L,int?i,ElemType?e){牋牋LNode?p=L;ink牋牋int爅=0;L;牋牋while(p-nextji),i牋牋wh{牋牋牋牋p=p-next;j
原创力文档

文档评论(0)