什麼是字典排序算法?
e.g. list[]={1,2,3}, 全排如下
對於三個數字(1,2,3),排列組合依次增大,就是字典序法。
e.g. 用字典序法找12354的下一個排列
註釋:對於1,2,3,4,5 。最大數字54321,最小數字12345 。稱12345完全順序,54321完全逆序。
如果當前排列是12354, 先要找到逆序區“54”
再找到逆序前的一個數字3
再找到逆序區比3大的最小數字4
再交換兩者得到12453
最後排序逆序區53,得到12435
至此算法中的一次迭代完成完成,還需要做的就是繼續迭代輸出所有結果。
例如list[]={1,2,3} 共有3*2*1=6次迭代,list[]={1,2,3,4}共有4*3*2*1=24次迭代。
總結起來:
1. 從這個序列中從右至左找第一個左鄰小於右鄰的數(從後向前查看逆序區域,找到逆序區域的前一位,也就是數字置換的邊界)
2. 把逆序區域的前一位和逆序區域中剛剛大於它的數字交換位置
3. 把原來的逆序區域轉爲順序
/**************************
功能:字典序算法
輸入:排序內容
輸出:字典序全排
***************************/
#include<stdio.h>
void show(int list[],int n);
void swap(int list[],int a,int b);
void bubbleSort(int list[],int a,int n);
void dictionaryOrderAlgorithm(int list[],int n);
int main()
{
int list[]={1,2,3,4,5,6,7,8,9};
int n=0;
printf("How many numbers:");
scanf("%d",&n);
dictionaryOrderAlgorithm(list,n);
}
void show(int list[],int n)
{
for(int i=0;i<n;i++)
printf("%d ",list[i]);
printf("\n");
}
void swap(int list[],int a,int b)
{
int temp=0;
temp=list[a];
list[a]=list[b];
list[b]=temp;
}
void bubbleSort(int list[],int a,int n)
{
int temp;
int flag=1;
while(flag==1)
{
flag=0;
for(int i=n-1;i>a+1;i--)
{
if (list[i]<list[i-1])
{
temp=list[i-1];
list[i-1]=list[i];
list[i]=temp;
flag=1;
}
}
}
}
void dictionaryOrderAlgorithm(int list[],int n)
{
//list[a]記錄第一個左比右小的數字
//list[b]記錄逆序區中最小的比list[a]大的數字
int a=0,b=0;
//計算循環輪次
int num=1;
for(int i=n;i>0;i--)
num=num*i;
for(int j=0;j<num;j++)
{
//展示當前情況
show(list,n);
//尋找list[a]
for(int i=n-1;i>0;i--)
{
if(list[i-1] < list[i])
{
a=i-1;
break;
}
}
//尋找list[b]
int min=65535;
for(int i=n-1;i>a;i--)
{
if(list[i] < min && list[i]>list[a])
{
b=i;
min=list[i];
}
}
//交換list[a]與list[b]
swap(list,a,b);
//排序逆序區
bubbleSort(list,a,n);
}
}