全排列递归算法

一道不怎么容易的算法题解决办法

http://www.cnblogs.com/sevendays/archive/2010/03/18/1689291.html 

 

读上文,有感而作 

 

给出一个递归算法;

1、将一个n维数组初始化,第0位填1,第1位填2.。。。。。 第n-1位填n;

2、将数组看为两部分,一个是已排好的,剩下是待排的,分别用两个指针指向;

3、将第一个字符,依次与后n-1个字符交换值,每次交换得到一个新的首数字;

4、剩下的n-1个数字按2、3步骤重复直至所有数组完成排列;

 

 

使用c++实现,代码还有些繁琐,明天再仔细看看优化一下

 

代码
 1 #include<iostream>
 2 using namespace std;
 3 
 4 void swap(int *p1,int *p2)
 5 {
 6     //交换p1和p2指向的值
 7     int tmp=*p1;
 8     *p1=*p2;
 9     *p2=tmp;
10 }
11 void output(int *p,int n)
12 {
13     while(n>0)
14     {
15         cout<<*p;
16         p++;
17         n--;
18     }
19     cout<<"\n";
20 }
21 
22 void fill(int *p1,int *p2,int len,int n)
23 {//p1指向已填满的部分,始终指向第一个;
24     //p2指向尚余下的部分,待插入那个;
25     //len表示已填部分的长度,n表示数组长度
26     if(len==n-1)
27         {
28             output(p1,n);//输出全部数组
29         }
30     else
31     {
32         int *p3,*p4;
33         int *pp=(int *)malloc(n*sizeof(int));
34         for(int i=0;i<n;i++)
35         {
36             *(pp+i)=*(p1+i);
37         }
38         p3=pp;
39         while(*p3!=*p2)
40         {
41             p3++;
42         }
43         p4=p3;
44 
45         for(int i=0;i<n-len;i++)
46         {            
47             swap(p3,p4);
48             p4++;
49             fill(pp,p3+1,len+1,n);
50         }
51     }
52 }
53 
54 void inti(int *p,int n)
55 {//将数组中所有的元素全部初始化,
56     int num=1;
57     while(num<=n)
58     {
59         *p=num++;
60         p++;
61         //cout<<num<<endl;
62     }
63 }
64 
65 int main()
66 {
67     int *p,n;
68     cout<<"请输入全排列规模:";
69     cin>>n;
70     p=(int *)malloc(n*sizeof(int));
71     inti(p,n);
72     fill(p,p,0,n);
73     return 0;
74 }

 

 

 

 

posted @ 2010-03-19 01:00 elite_lcf 阅读(2464) 评论(10) 编辑 收藏

 回复 引用 查看   
#1楼 2010-03-19 07:08 徐少侠      
园子里以前有几个朋友研究过,搞出几种做法的
等下找找看,大家再来学习下。
呵呵

 回复 引用 查看   
#2楼 2010-03-19 09:24 Sevendays      
哈哈,学习学习~
 回复 引用 查看   
#3楼 2010-03-19 09:36 Sevendays      
启发我了,我再写个试试~谢谢~
 回复 引用 查看   
#4楼 2010-03-19 09:45 AutumnWinter      
以前也写过,凑个热闹
#include <iostream>
using namespace std ;

void Output(int a[], int n)
{
	for (int i = 0; i < n; i++)
		cout << a[i] ;
	cout << endl ;
}

void Perm(int a[], int l, int t) 
{ 
	if (t == l) 
		Output(a, t); 
	else 
	{ 
		for (int k = t; k < l; k++) 
		{ 
			swap(a[k], a[t]); 
			Perm(a, l, t + 1); 
			swap(a[k], a[t]); 
		} 
	} 
} 

int main(void)
{
	int n ; 
	cout << "input n:" << endl ;
	cin >> n ;

	int *a = new int[n] ;
	for (int i = 0; i < n; i++)
		a[i] = i + 1 ;

	Perm(a, n, 0) ;

	system("pause") ;
	return 0 ;
}

 回复 引用 查看   
#5楼 2010-03-19 09:48 AutumnWinter      
你应该在外部将数组初始化好然后传递给生成排列的函数,而不是在函数内部递归的调用malloc来分配内存,这样效率太低了。
 回复 引用 查看   
#6楼 2010-03-19 10:45 devil0153      
我之前也写过,不过不是递归,效率更高效:)
 回复 引用 查看   
#7楼[楼主] 2010-03-19 11:41 elite_lcf      
@AutumnWinter
受教了!

 回复 引用 查看   
#9楼 2010-03-20 22:18 AutumnWinter      
 回复 引用 查看   
#10楼 2010-05-13 11:20 karlzheng      
http://elite-lcf.blog.hexun.com/39488237_d.html

序列三:k+1, k+2, k+3, …, n-2, n-1, n, 1, …, k-2, k-1

序列四: 1 , 2 , 3 , …,n-k-2, n-k-1, n-k, n-k+1, …,n-2, n-1

又∵ k=m%n;
∴ x' = x+k = x+ m%n ; 而 x+ m%n 可能大于n
∴x'= (x+ m%n)%n = (x+m)%n

证毕
===========================================
这一个中怎么证明x'=x+k

知识共享许可协议
本博客采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。