字典序排列
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
p1…pj-1 pkpj+1pk-1 pj pk+1…pn (4) 将pk 后面的序列逆序,得到下一个排列 p1…p j-1pk pnpk+1 pj pk-1 ….pj+1
3
例 设有排列2763541, 按照字典式排序, 它 的下一个排列是? (1) 2763541 [3是第一个比其右边小的数] (2) 2763541 [4是3后面比3大的最小的数] (3) 2764531 [交换3,4的位置] (4) 2764135 [把4后面的531逆序排列为 135即得到下一个排列]
(1)从排列 p 的右端向左开始,找出第一个比其右边数字小的数 字记其下标为 j (2)在 pj 的右边的数字中,找出比 pj 大的数中最小的数字pk
由于 pj 右边的数从左到右是递减的,因此 pk 是所有大于 pj 的数字中下标最大者,所以也就是要找到比 pj 大且下标最大 的数 (3) 互换pj与pk得
7
3. 将a[i]与a[k]互换位置
void exchange(int a[],int i,int k) { int temp; temp=a[i]; a[i]=a[k]; a[k]=temp; }
8
4. 将a[i]后面的序列逆序
i=search1(a); len = sizeof(a)/sizeof(int); for(m=i+1,n=len-1;m<n;m++,n--) { temp=a[m]; a[m]=a[n]; a[n]=temp; }
字典树
字典树与字典很相似,当 你要查一个单词是不是在字 典树中,首先看单词的第一个 字母是不是在字典树的第一 层,如果不在,说明字典树里 没有该单词,如果在就在该字 母的孩子节点里找是不是有 单词的第二个字母,没有说明 没有该单词,有的话用同样的 方法继续向下查找. 在查找的过程中会产生多个字母序列,那么可以使用字典 树的方法对一串数字进行全排列。
5
字典序算法实现
1. 找出从右到左第一个小于它右边数的数,返回其数组下标 i1 int search1(int a[]) { int i; for(i=len-1;i>=1;i--) { if(a[i-1]<a[i]) //数组下标从0开始 return i-1; } return -1; }
6
2. 找到 a[i]右边比a[i]大的下标最大的数,返回其数组下标k int search2(int a[],int n) { int k; for(k=len-1;k>n;k--){ if(a[k]>a[n]) return k; } return -1; }
9
4
例 设S=1,2,3,4, 用字典序法求出S的全 部排列. 解 1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321.
1
图1.11是一棵高度为4的树,按从根节点到叶子节点依次向下搜索并 读出边的标号顺序,自左向右,依次为1234,1243,1324,134…,即 1,2,3,4的全排列。
问题:已知一个排列,如何得出下一个排列
2
字典序法算法
பைடு நூலகம்
求(p)= p1…pj-1 pjpj+1pk-1 pkpk+1…pn的下一个排列:
3
例 设有排列2763541, 按照字典式排序, 它 的下一个排列是? (1) 2763541 [3是第一个比其右边小的数] (2) 2763541 [4是3后面比3大的最小的数] (3) 2764531 [交换3,4的位置] (4) 2764135 [把4后面的531逆序排列为 135即得到下一个排列]
(1)从排列 p 的右端向左开始,找出第一个比其右边数字小的数 字记其下标为 j (2)在 pj 的右边的数字中,找出比 pj 大的数中最小的数字pk
由于 pj 右边的数从左到右是递减的,因此 pk 是所有大于 pj 的数字中下标最大者,所以也就是要找到比 pj 大且下标最大 的数 (3) 互换pj与pk得
7
3. 将a[i]与a[k]互换位置
void exchange(int a[],int i,int k) { int temp; temp=a[i]; a[i]=a[k]; a[k]=temp; }
8
4. 将a[i]后面的序列逆序
i=search1(a); len = sizeof(a)/sizeof(int); for(m=i+1,n=len-1;m<n;m++,n--) { temp=a[m]; a[m]=a[n]; a[n]=temp; }
字典树
字典树与字典很相似,当 你要查一个单词是不是在字 典树中,首先看单词的第一个 字母是不是在字典树的第一 层,如果不在,说明字典树里 没有该单词,如果在就在该字 母的孩子节点里找是不是有 单词的第二个字母,没有说明 没有该单词,有的话用同样的 方法继续向下查找. 在查找的过程中会产生多个字母序列,那么可以使用字典 树的方法对一串数字进行全排列。
5
字典序算法实现
1. 找出从右到左第一个小于它右边数的数,返回其数组下标 i1 int search1(int a[]) { int i; for(i=len-1;i>=1;i--) { if(a[i-1]<a[i]) //数组下标从0开始 return i-1; } return -1; }
6
2. 找到 a[i]右边比a[i]大的下标最大的数,返回其数组下标k int search2(int a[],int n) { int k; for(k=len-1;k>n;k--){ if(a[k]>a[n]) return k; } return -1; }
9
4
例 设S=1,2,3,4, 用字典序法求出S的全 部排列. 解 1234, 1243, 1324, 1342, 1423, 1432, 2134, 2143, 2314, 2341, 2413, 2431, 3124, 3142, 3214, 3241, 3412, 3421, 4123, 4132, 4213, 4231, 4312, 4321.
1
图1.11是一棵高度为4的树,按从根节点到叶子节点依次向下搜索并 读出边的标号顺序,自左向右,依次为1234,1243,1324,134…,即 1,2,3,4的全排列。
问题:已知一个排列,如何得出下一个排列
2
字典序法算法
பைடு நூலகம்
求(p)= p1…pj-1 pjpj+1pk-1 pkpk+1…pn的下一个排列: