[アルゴリズム] リストの順列

私は順列のプログラムのリストを作成します {1, 2, …, N} 注文辞書.
例えば、= Nと 3, 私は十分にリストしました 6 変換:

1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1

したがって、最初の順列は<1であります, 2, …, N>. 最終転置<nの, -1, …, 1>.

現行順列よりも大きくなる順列を生成します, ご注文時に十分な順列よりも大きな電流順列は、それらの間で意味の他の順列を持つことはできません. 現行順列をされていると仮定すると= <3, 2, 6, 5, 4, 1>, レビュー 4 最後の要素, 私は、彼らが下降している参照してください。, それは我々が順列を持っている場合でも、ということを意味します 4 どのようにこの要素, これは、もう少し順列現行順列ました. だから我々は、アカウントAに取らなければなりません[2] = 2, 別の値に置き換え. 私は値に置き換えます?, することはできません 1 とても小さいの順列であるかどうので、, することはできません 3 持つため[1] = 3 すでに (次の要素は、要素を選択し、以前の値に選択されていません). 残りの値 4, 5, 6. 私たちが選択したように、十分に大きな電流順列を必要に応じて[2] = 4. そして、値 (ザ·[3], ザ·[4], ザ·[5], ザ·[6]) 実際にはかかります {2, 6, 5, 1}. また、十分な大きさのためには、私たちは最小の表現を見つけます 4 に割り当てられたこの数[3], ザ·[4], ザ·[5], ザ·[6] すなわち、<1, 2, 5, 6>. だから、新しい順列がある<3, 4, 1, 2, 5, 6>.

私はこの例をその上にコメントを持っています: 現行順列の終わりが下降され、, の[5] = 4 最後の段落内の最小数は、より大きな満足する条件を降順[2] = 2. スワップ場合[5] 以下のために[2] 私は次のようになります[2] = 4 そして最後は、降順にソートすることはまだあります. それは最終的には最小値に対して実行したかったとき、私たちは最後の段落を逆転します. 現在の順列の場合は<2であります, 1, 3, 4>次の順列は<2であります, 1, 4, 3>. 我々はまた、順列を考慮することができる<2, 1, 3, 4>テーパー形状の端, この最後の部分は構成されてい 1 要素 (4) だから、次のように次の順列順列からの学生が今構築することができますエンジニアリング:

  1. 最長のテーパ状の端部を決定, 要素のインデックスiを探して[で] 後半に始まりました. これは最初の要素の行まで下から見て意味します 2 (あなたは最終転置である最初の要素を見れば、その必要はありませんので、), 私が最初に満たすインデックスを検出しました[iは、1] < ザ·[で].
  2. あなたは上記のインデックス私を見つけた場合
    – エンド降順で, A要素を見つけます[へ] 条件Aを満足する最も小さいです[へ] > ザ·[iは、1]. 末端の減少に起因します, これは、最初のインデックスのkを満たすaを満たすために、範囲の上端から見ることによって行われます[へ] > ザ·[iは、1] (バイナリ検索を使用することができます).
    – 島の価値があるのA[へ] と[iは、1]
    – 覆さエンド降順 (から[で] へ[へ]) 昇順になります.
  3. あなたが見つからない場合は、全範囲すなわち降順程度でした, これは最終的な構成であります.

C ++コードが示して.

/*
code by nguyenvanquan7826
*/

#include <cstdio> 
#include <cstdlib>
#include <iostream>
#include <algorithm>		// thu vien chua ham swap (hoan vi 2 so)
using namespace std;

int main(int argc, char **argv)
{
	int n, *a;
	scanf("%d", &n);
	a = new int[n];
	for (int i=0; i<n; i++)			// khoi tao va in ra cau hinh ban dau
	{
		a[i] = i+1;
		printf("%d   ", a[i]);
	}	
	printf("n");
	
	int i = n-1;		// i la vi tri ma doan cuoi giam dan
	while (i>0)			// trong khi doan cuoi khong phai bat dau tu vi tri dau tien
	{
		i = n-1;
		while (a[i] < a[i-1])	// tim vi tri dau tien ma doan cuoi giam dan
		{
			i--; 
		}
		
		if (i>0)		// Neu tim duoc i
		{
			int k;		// tim so a[k] nho nhat trong doan giam dan ma a[k] > a[i-1]
			for (k = n-1; k >= i; k--)		
			{
				if (a[k] > a[i-1])		
				{
					break;
				}
				
			}
			swap(a[k], a[i-1]);		// hoan vi a[k] va a[i-1]
			
			// dao nguoc doan cuoi giam dan thanh tang dan
			for (int k = i; k < i + (n - i) / 2; k++)	
			{
				swap(a[k], a[n - 1 - k + i]);
			}
			
			for (int k = 0; k < n; k++)		// in hoan vi ra
			{
				printf("%d   ", a[k]);
			}
			printf("n");
		}
	}
	
	return 0; 
}

記事より引用 教科書のデータ構造と氏はル・ミン・ホアンのアルゴリズム. あなたが書いたようにあなたがシラバスで見ることができるパスカルコード.