第一次写,有点小激动!
编程对于工科学生的重要性不言而喻,如果你喜欢这篇文章,欢迎一起交流学习!
什么是字典排序算法?
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. 把原来的逆序区域转为顺序
欢迎交流:mate595@qq.com
/**************************
作者:MATE
功能:字典序算法
输入:排序内容
输出:字典序全排
***************************/
#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);
}
}