关于全排列的算法
我在网上看到有人用递归写了一个全排列的算法,感觉写得很不错,贴出来大家学习一下。主要的思想是元素的交换。比如,有这样的数组{1,2,3,4},能够获取的全排列有{1,2,3,4},{1,2,4,3},{1,3,2,4},{1,3,4,2},{1,4,2,3},{1,4,3,2}....{4,1,2,3}。void swap(int &x, int &y)
{
int tmp = x;
x = y;
y = tmp;
}
void perm(int list[], int start, int end)//start起始下标,end尾元下标
{
int index;
if(start > end)
{
for(index = 0; index <= end; index++)
{
printf("%d ", list[index]);
}
printf("\n");
}
else
{
for(index = start; index <= end; index++)
{
swap(list[index], list[start]);
perm(list, start + 1, end);
swap(list[index], list[start]);
}
}
}
但这个算法还是有可以改进的余地,你仔细观察它每次交换的变换,会发现有很多时候,其实根本用不着交换元素,也就是说该算法存在不必要的调用。我们只要加上几句判断,就可以避免多余的函数调用。在for循环里比较index和start的值,如果不等才调用swap方法。其实,我们可以换个角度思考问题,我们并不一定要交换元素,其实我们还可以交换元素的位置。如果能找到某种算法,对于不同的排列,我们只是针对下标的变换,而不是内部元素的变换,那么完全可以不用交换方法,也就是不去修改数组,就能完成任务呢。大家不妨也思考一下,一起交流。如果我想到了更好的解决方法,会第一时间跟大家交流。请新手们牢记,如果想学好c,不是你看到别人的方案,拷贝粘贴就完事了,要思考一下为什么是这样做,是否存在可改进的地方,假如换个方法,是否能更好,这样才能进步。