实现全排列的两种算法:字典序列法以及递归算法(java)

本文详细介绍两种全排列算法:字典序列法与递归算法。字典序列法适用于数据重复情况,通过查找并交换字符实现全排列;递归法则用于无重复数据场景,采用分解组合思想完成排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.全排列之字典序列法

/**
	 * 这是一个实现全排列的字典序列算法,可适用于有数据重复以及无数据重复的字符串----注意:字符要先从小到大排序
	 * 算法描述:例如:645321的下一个数:
	 * 1.左边的数要大于右边:从最右->最左,遍历查询是否有邻近左边的数小于右边的数,有就停止遍历,本例:4<5.
	 * 2.把找到的左边那个数,与其右边的所有数比较,从右向左逐一比较,找到第一个比它大的,然后交换。本例:比4大的右边第一个数是5.
	 * 3.将两个数对换,则字符可分为65,4321,把"4321"从小到大排序:1234* 4.下一个字符序列是:651234.
 <span style="white-space:pre">	</span> * 总结:程序就是找出人脑解决问题的经验的逻辑规律用科学的方法表述出来,提高效率及确保准确性.
	 * 
	 * @param ary //要排列的数组
	 */
	public static void dictorySerial(int[] ary1) {
		Arrays.sort(ary1);
		System.out.println("1:" + Arrays.toString(ary1));
		int i = 2;
		while (true) {
			int j;
			for (j = ary1.length - 1; j > 0; j--) {
				if (ary1[j - 1] < ary1[j]) {
					for (int k = ary1.length - 1; k > j - 1; k--) {
						if (ary1[k] > ary1[j - 1]) {
							int temp = ary1[j - 1];
							ary1[j - 1] = ary1[k];
							ary1[k] = temp;
							break;
						}
					}
					int[] ary2 = new int[ary1.length - j];
					System.arraycopy(ary1, j, ary2, 0, ary2.length);
					Arrays.sort(ary2);
					System.arraycopy(ary2, 0, ary1, j, ary2.length);
					System.out.println((i++) + ":" + Arrays.toString(ary1));
					break;
				}
			}
			if (j == 0) {
				break;
			}
		}
	}

二.全排列之递归算法

/**
	 * 这是关于java全排列的递归算法,本算法不适用于字符串中有重复数字。 ---注意:交换两个数后,后面要在交换过来,不要影响要排列的字符序列(*)
	 * 算法过程:如:123的全排列:
	 * 1.可以看成:以1开头的全排列,以2开头的全排列,以3开头的全排列</span>表示成1(23),2(13),3(12)的全排列,即23全排列,13全排列,12全排列.
 <span style="white-space:pre">	</span> * 2.23全排列可以看成:以2开头的全排列,表示成2(3) ,<span style="font-family: Arial, Helvetica, sans-serif;">以3开头的全排列,表示成3(2),13全排列可以看成:以1开头的全排列,表示成1(3),以3开头的全排列,表示成3(<span style="white-space:pre">			</span> 1),</span><span style="font-family: Arial, Helvetica, sans-serif;">12全排列可以看成:以1开头的全排列,表示成1(2),以2开头的全排列,表示成2(1). 
 <span style="white-space:pre">		</span>* 3.而当只有一个数全排列时,就是其本身,也就是终止条件.
	<span style="white-space:pre">	</span> * 4.所以123全排列为123,132,213,231,312,321;
	<span style="white-space:pre">	</span> * 
	<span style="white-space:pre">	</span> * 总结:递归就是挖掘出解决这件事情的子步骤的共同步骤,即共同运行规律!本例就是全排列分解出来的各个子排列的共同规律。
	<span style="white-space:pre">	</span> * 
	<span style="white-space:pre">	</span> * @param ary2
	<span style="white-space:pre">	</span> *            要排序的字符序列
	<span style="white-space:pre">	</span> * @param start
	<span style="white-space:pre">	</span> *            字符序列要全排列的的开始元素
	<span style="white-space:pre">	</span> * @param end
	<span style="white-space:pre">	</span> *            字符序列要全排列列的终止元素
	<span style="white-space:pre">	</span> */
	public static void recurrence(int[] ary2, int start, int end) {
		if (start == end) {
			System.out.println((++i) + ":" + Arrays.toString(ary2));
		} else {
			for (int i = start; i <= end; i++) {
				swap(ary2, start, i);
				recurrence(ary2, start + 1, end);
				swap(ary2, start, i);
				System.out.println(Arrays.toString(ary2));
			}
		}
	}

	public static void swap(int[] ary2, int start, int i) {
		int temp = ary2[start];
		ary2[start] = ary2[i];
		ary2[i] = temp;

	}</span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值