Java用遞歸實現全排列,詳細


package edu.cqu.algorithmTest;

import java.util.Scanner;


// 全排列,遞歸實現
public class Main8 {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3};
        bfs(arr, 0, arr.length - 1);
    }
    
    public static void bfs(int []a,int start,int end) {
    	/*
    	 * 遞歸的終點是,我們拿着start去逐個和后面的集合考慮要不要交換:
    	 * 當需要交換時,我們交換,start+1
    	 * 當不需要交換時,我們不交換,start還是要加1,因為我們要靠着start進入遞歸的最底層
    	 * 一直start比較到最后了,交不交換都反正都結束了,我們打印處結果。然后返回到遞歸的上一層。
    	 * 在上一層(我們的start后退一步),搜索是否應該和start交換的i也加1了。
    	 * 如處理{1,2,3}全排列
    	 * 相當於在處理完{2,3}的全排列后,
    	 * 我們回到上一層,start到了{1},此時需要考慮將{1} 和{2,3}里面交換。i就是去尋找2,3的
    	 * 
    	 * 
    	 * */
    	if(start == a.length) {
    		for(int i:a) {
    			System.out.print(i);
    		}
    		System.out.println();
    		
    	}
    	
    	for(int i = start;i < a.length;i++) {
    		if(isUnique(a,start,i)) {
    			swap(a,start,i);
        		bfs(a,start+1,i);
        		/*
        		 * 為什么要再交換呢?
        		 * 你比如還是{1,2,3},我拿着{1}去交換{2,3}中間的{2},交換完成之后,
        		 * 顯然成了{2} {1,3} 即2,1,3和2,3,1  
        		 * 但是,我還要拿{1}去換{2,3}中的3啊,數組成了[2,1,3][2,3,1]我再拿第一個位置交換第三個位置顯然亂套
        		 * 所以,我們恢復原樣。當遞歸完成,回到上一層的時候,上一層的start,i還在哪給你記着呢,你本來換了哪個數
        		 * 原原本本給換回來。每一層都一樣,所以不會亂。
        		 * 
        		 * 
        		 * */
        		swap(a,start,i);
        	}
    		
    	}
    }
    
    static boolean isUnique(int a[],int start,int end ) {
    	/*
    	 * //如果在需要被交換的數a[end]之前出現了和它一樣的數,例如{1}想要交換到{2,3,4}中的4沒有問題,
    	 * 換完之后組成新的集合{2,3,1}進行遞歸,遞歸會處理好{2,3,1}的全排列
    	 * 但是如果{1}想要和{4,3,4}中的后面一個4進行交換就需要排除,因為當{1}和第一個4交換,已經將{1,3,4}的全排列
    	 * 結果全部給出了。
    	 * 因此,我們逐個檢查a[end]這個元素之前,有沒有和它 一樣的數
    	 * 
    	 * 
    	 * */
    	for(int i = start ;i < end; i++) {
    		if(a[i] == a[end]) {
    			return false;
    		}
    	}
    	return true;
    }

    
    
    
    public static void swap(int []a,int m,int n) {
    	int t = a[m];
    	a[m] = a[n];
    	a[n] = t;
    }

}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM