c 语言实现全排列和组合

求全排列的话有两种方法:

方法一:利用递归,将一个排列看成是以一个数开头+另外一个子排列,  例如数组list[n]的全排列,以list[i]表示以元素list[i]开头的一个排列,所以所有的排列数为list[0]+list[1]+list[2].......list[n-1],    以list[i]为首元素的排列可以看成是list[i] 为首,加上另外n-1个元素排列的排列。这里每次以list[i]为首时候,可以将list[i]和list[0]交换元素,然后求自序列list[1]----list[n-1]的排列,就可以递归下去

/*
 * recursion 
 */
void full_rank_recurisive(int *list,int n,int num)
{
	if(num == n)
	{
		print_list(list,list+n);
		putchar('\n');
		return;
	}
	int i ;
	for(i = num;i<n;i++)
	{
		swap(&list[i],&list[num]);
		full_rank_recurisive(list,n,num+1);
		swap(&list[i],&list[num]);
	}
}

方法二:不采用递归的方法,首先将数组看成是一个递增的,这与我们手写排列是一个习惯,每次从右边找到第一个元素,这个元素比他右边的元素小,他右边的元素都是单调递减的,然后再从右边重新扫描,找到第一个比他大的元素,交换元素值,然后再将他右边的元素从小到大排列,如此循环,知道找不到那个元素为止

void full_rank(int *p_start,int *p_end)//inorder from little to big
{
	print_list(p_start,p_end);
	putchar('\n');
	while(1)	
	{
		int *ptr = p_end - 2;
		for(;ptr !=p_start - 1; ptr--)
		{
			if(*ptr < *(ptr+1))
				break;
		}
		if(ptr == p_start - 1)
			break;

		int *p2 = p_end - 1;
		for(;p2 != ptr;p2--)
		{
			if(*p2 > *ptr)
				break;
		}
		swap(ptr,p2);
		qsort(ptr+1,p_end - ptr-1,sizeof(p2[0]),cmp);

		print_list(p_start,p_end);
		putchar('\n');
	}
}
关于组合,使用递归或者穷举,每个数要么被选,要没不被选,就这两种选择

void DFS(int *src,int *dest,int n,int m, int k,int index)
{
	if(k == m || index == n)	
	{
		print_list(dest,dest+m);
		putchar('\n');
		return;
	}
	if(n - index == m - k)
	{
		for(;index<n;)
			dest[k++] = src[index++];
		print_list(dest,dest+m);
		putchar('\n');
	}
	else{
		dest[k] = src[index];
		DFS(src,dest,n,m,k+1,index+1);
		DFS(src,dest,n,m,k,index+1);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值