`

排列组合 递归和非递归算法实现

阅读更多

一、全排列的递归算法

       例如:一组数 A B C D

                 结果就是 A开头的全排列

                                ---B和C和D开头的全排列

                                ---------------C和D开头的全排列

                                ---------------------------- D开头的全排列

                                B开头的全排列

                                C开头的全排列

                                D开头的全排列

                 后面N-1个元素分别于第N元素交换,当数组只有一个的时候便是出口了。

	public static void full_array_test1(char[] a,int start,int end){
	  //首先当start=end的时候结束那个递归
		if(start==end){
			FULL_ARRAY_COUNT++;
			for(int i=0;i<=end;i++){
				System.out.print(a[i]+" ");
			}
			System.out.println();
		}else{
			//下一个元素交换
			for(int i=start;i<=end;i++){
				char temp=a[start];
				     a[start]=a[i];
				     a[i]=temp;
				//递归下一个
				     full_array_test1(a,start+1,end);
			    //还原数据
				     temp=a[start];
				     a[start]=a[i];
				     a[i]=temp;
			}
		}
	}

 二、非递归方法

 

 

1.前提是排过序的 从小到大   例如:12345

2.那么最大的值是                              54321

                                              那么:21345 的下一个数是:21354

                                                                        下一个数是:21435

3.那么位置在这两个中间的就是我们要求的

------------------------------------1.判断是否到终点了,就是一个最大的排列。

                                              判断方法从右边到左边如果不是递增的就ok  记录下位置index

 -----------------------------------2.根据上面提供的index然后确保找到比index-1《index2《index的一个最小值

 -----------------------------------3.交换1和2产生的位置的值

 -----------------------------------4.在交换位置的地方1的值后面 需要倒排

                                            (因为后面是递减的,转换后是递增,然后从新排列)

 -----------------------------------5.输出排列的组合

 //从最右边判断是否右边的数有比较左边的数大的有的话说明这个这个数有后继者
	public static int indexBig(char[] a){
		int index=-1;
		for(int j=a.length-1;j>=1;j--){
			if(a[j]>a[j-1]){
				index=j;
			break;
			}
		}
		return index;
	}
	//有后继者后得到了 右边比左边的数大的位置了 然后查找比一个最小的比他大的数
	public static int indexMinMax(char[] a,int indexMax){
		int index=indexMax;
		char temp=a[indexMax];
		for(int i=indexMax;i<a.length;i++){
			if(a[i]>a[indexMax-1]&&a[i]<temp){
				index=i;
				temp=a[i];
			}
		}
		return index;
	}
////交换
	public static void change(char[] a,int i ,int j){
		char temp=a[i];
		    a[i]=a[j];
		    a[j]=temp;
	}
	//对于交换的数位置之后的数进行倒叙排列 其实是一个排序
	//应该怎么进行的哪?
	public static void oppsiteDirectory(char[] a,int index){
		 
		for(int i=index;i<((a.length-index)/2+index);i++){
		 char temp=a[i];
		      a[i]=a[a.length-1-(i-index)];
		      a[a.length-1-(i-index)]=temp;
		}
	}
	//输出字符数组的
	public static void print(char[] a){
		for(int i=0;i<a.length;i++){
			System.out.print(a[i]+" ");
		}
		System.out.println();
	}

 

 

 

               String ss="123456";
		a=ss.toCharArray();
		print(a);

		int index1=-1;
	        int index2=-1;
	    int count=1;
		while(true){
			//首先检测
			
		    index1=indexBig(a);
			if(index1==-1)
				break;
			index2=indexMinMax(a, index1);
			change(a, index1-1, index2);
			oppsiteDirectory(a, index1);
			print(a);
			count++;
		}
		System.out.println(count);

 

 三、组合的算法

//递归算法
static void combine( int a[],int n,int m,int b[] )
	{ 
	 for(int i=n; i>=m; i--)  
	 {
	  b[m-1] = a[i-1];
	  if (m > 1)
	   combine(a,i-1,m-1,b);
	  else                    
	  {   
	   System.out.println(Arrays.toString(b));
	  }
	 }
	}

 

//按照网上的10转换
	//输出有10的位置第一次位置 
	//然后调整为01
	//10左边的移动到左边
	static void combine2(int[]a,int n,int m,int[] b){
	 for(int i=0;i<m;i++)
		 b[i]=1;
	 do{
		 printArray(b,a);
	 }while(getFirstFlage(b,n,m)!=-1);
	}
	
	static int getFirstFlage(int[]b,int n,int m){
		int count=0;
		for(int i=0;i<n-1;i++){
			
			if(b[i]==1&&b[i+1]==0){
			     	//交换位置
				    b[i]=0;
				    b[i+1]=1;
				    //移动
				    for(int j=0;j<count;j++){
				    	b[j]=1;
				    }
				    for(int k=count;k<i;k++)
				    	b[k]=0;
				   // System.out.println(count+"=="+Arrays.toString(b));
				 return i;
			}else if(b[i]==1){
				count++;
			}
		}
		return -1;
	}
	static void printArray(int[]b,int[]a){
		for(int i=0;i<b.length;i++){
			if(b[i]==1)
			System.out.print(a[i]+" ");
		}
		System.out.println();
	}
	public static void main(String[] args) {
	 
	    int[] a=new int[]{1,2,3,4,5,6,7,8};
	    int[] b=new int[8];
	    combine2(a,a.length,3,b);
		//combine(a,a.length,2,b);
		//System.out.println("总的个数:"+k);
	}

 

 

分享到:
评论

相关推荐

    C#实现排列组合算法完整实例

    其实排列实现了,组合也就实现了,组合C(N,R)就是P(N,R)/P(R,R) ,实现这一功能比较简单的是递归算法,但考虑到递归的性能,下面采用了2种非递归的方法,具体代码如下 using System; using System.Collections....

    汉诺塔递归与非递归两种算法的代码与结果对比

    "非递归解决汉诺塔,每一步都有确切解.doc"文件很可能提供了非递归算法的详细步骤和解释,每一步都确保了盘子的合法移动,确保最终能将所有盘子从A移动到C。 **结果对比** "no differences"的结果表明,无论使用...

    递归求全排列算法

    此方法能够生成排列的字典序,易于理解和实现,但在处理大量数据时效率较低。 2. **递增进位数制法**:通过类似十进制加法的方式,利用中介数生成下一个排列。这种方法减少了不必要的元素移动,提高了算法效率,但...

    排列(递归与非递归)算法及接口设计

    NULL 博文链接:https://lifethinker.iteye.com/blog/263104

    c++ 排列组合算法,代码简单

    根据给定的文件信息,我们可以总结出以下...然而,对于大规模数据集,应注意性能优化,例如使用迭代而非递归,或应用更高效的算法变体。此外,确保良好的代码结构和错误处理机制,对于编写健壮和可靠的程序至关重要。

    Hanoi塔问题的一种非递归算法

    ### Hanoi塔问题的一种非递归算法:深入解析与实现 #### 一、引言 Hanoi塔问题作为计算机科学领域内经典的递归问题之一,因其简洁性和挑战性而广受关注。通常,Hanoi塔问题的解决方案多采用递归算法,尽管其逻辑...

    基于c语言的排列组合算法

    在编程领域,排列和组合是两种基本的数学概念,它们被广泛应用于算法设计,尤其是在解决计数问题和遍历所有可能性时。C语言作为一种强大的、底层的编程语言,经常被用来实现这些算法,以提高效率和灵活性。在这个...

    合并排序算法非递归形式源码

    通过分析和理解`mergeSort.c`的源码,你可以学习到C语言编程技巧,如指针操作、数组处理以及如何构建和优化非递归算法。此外,结合实际运行代码,还可以加深对合并排序算法工作原理的理解,并可能启发你对其他排序...

    hanoi塔非递归.rar

    非递归算法实现汉诺塔的方法通常基于迭代或栈的思想。这种算法不是直接通过函数递归调用来解决,而是通过循环结构和数据结构来模拟递归过程。以下是使用非递归算法解决汉诺塔问题的基本步骤: 1. **定义数据结构**...

    汉诺塔非递归算法 数据结构

    非递归算法通常在处理此类问题时更利于理解与实现,特别是对于初学者或内存限制较大的情况。 在这个非递归算法中,我们主要利用了栈这种数据结构。栈是一种后进先出(LIFO)的数据结构,非常适合用来模拟递归过程,...

    N个数全排列的非递归算法

    在这个场景中,非递归算法指的是不依赖递归函数来实现这一计算过程的方法。 在描述中提到了一个博客链接,虽然具体内容没有给出,但通常博主会详细解释如何用非递归的方式解决全排列问题。非递归算法通常采用迭代或...

    c语言实现的排列组合程序

    在编程领域,排列和组合是两个重要的概念,它们在解决许多问题时都会被用到,尤其是在算法设计中。本文将详细探讨如何使用C语言来实现排列组合算法,并结合递归解决P(m,n)问题。 首先,我们要理解排列和组合的基本...

    快排与二分检索递归与非递归

    这两种算法都涉及到递归和非递归的实现方式,各有优缺点。下面我们将深入探讨这两个算法的递归与非递归实现及其原理。 **快速排序** 快速排序是一种基于分治思想的排序算法,由C.A.R. Hoare在1960年提出。其基本...

    C语言数据结构中序遍历的非递归算法

    本节我们将深入探讨非递归实现的中序遍历算法。 首先,理解中序遍历的基本概念是关键。对于一个二叉树,中序遍历的结果可以得到一个按升序排列的节点序列(假设左子树小于根节点,根节点小于右子树)。递归版本的...

    递归和非递归建立树和树的前,中,后,分层遍历

    在计算机科学中,树是一种非常重要的数据结构,广泛应用于各种算法和问题解决中。树的遍历是理解和操作树的关键步骤。本主题将深入探讨如何使用递归和非递归方法来建立树,并实现前序、中序、后序以及分层遍历。 **...

    二叉树的遍历(递归+非递归 c语言版)

    本篇文章将详细介绍这三种遍历方法,并通过C语言实现递归和非递归版本。 1. 前序遍历(根-左-右) 在前序遍历中,我们首先访问根节点,然后遍历左子树,最后遍历右子树。递归实现非常直观,代码如下: ```c void...

    c语言,二叉树,前中后,递归,非递归

    非递归遍历方法通常使用栈来实现,这样可以避免递归调用带来的性能问题。 #### 前序遍历的非递归实现 非递归前序遍历首先访问当前节点,然后将其入栈,并将指针指向左孩子,直至左孩子为空或到达叶子节点。此时,从...

    全排列-非递归算法

    非递归算法的优点在于它可以避免深度过大的调用栈,从而在处理大型数据集时减少内存消耗。这里以1到6的数字为例,我们可以构建一个迭代的解决方案来生成全排列。首先,我们需要一个容器,例如数组或列表,来存储当前...

    组合排列组合排列组合排列组合排列

    压缩包中的文件名为“Zuhe”,可能是实现组合排列算法的Java源代码文件。通过查看这个文件,我们可以了解具体的实现细节,包括使用的数据结构、递归或非递归的策略,以及如何处理边界条件等。 总的来说,组合排列是...

    递归求解几类排列组合问题

    递归求解几类排列组合问题 ...递归法可以用来解决各种复杂的排列组合问题,它可以减少代码的复杂度和可读性。但是,需要注意递归法的使用也需要设计好一个或若干个确定的递归终止条件,以免出现栈溢出或其他问题。

Global site tag (gtag.js) - Google Analytics