Chinaunix首页 | 论坛 | 博客
  • 博客访问: 624129
  • 博文数量: 127
  • 博客积分: 6136
  • 博客等级: 准将
  • 技术积分: 1461
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-24 00:32

分类: C/C++

2011-04-25 17:35:05

最近由于面试需要,开始逐渐研究起算法来,全排列生成算法我一直没弄明白,今天趁着有时间,看了一下,觉得算法不是很复杂。下面介绍的是字典序法的全排列生成算法。
算法思路就是:
1】从序列的末端开始,找到第一个数组合(可以不必相邻),其中第一个数小于第二个数,比如:1 2 3 4,第一个组合是34,记录3的位置为i;
2】从i位置之后的元素中,从末端开始找一个大于它的最小数,就是4,交换这两个数;
3】将i位置之后的数全部逆序,这样就生成了字典顺序的下一个序列;
4】执行步骤1;
算法实现如下:

#include <stdio.h>
#include <stdlib.h>

int array_size = 0;
int *dic;
void show()
{
    int i=0;
    for(i=0; i<array_size; i++)
    {
        printf("%d ", dic[i]);
    }
    printf("\n");
}
void swap(int *a, int *b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void reverse(int start, int end)
{
    while(start < end)
    {
        swap(&dic[start], &dic[end]);
        start++;
        end--;
    }
}

int main(int argc, char *argv[])
{
    int size = atoi(argv[1]);
    int i, n = size, j;
    array_size = size;
    dic = (int *)malloc(size * (sizeof(int)));
    for(i=0; i<size; i++)
    {
        dic[i] = i+1;
    }
    show();
    i = n-1;
    while(i >= 0)
    {
        int max = 1000, cur = -1;
        for(j=n-1; j > i; j--)
        {
            if(dic[j] > dic[i] && dic[j] < max)
            {    
                cur = j;

                max = dic[j];
            }
        }
        if(cur != -1)
        {
            swap(&dic[i], &dic[cur]);
            reverse(i+1, n-1);
            show();
            i = n-1;
        }
        else
            i--;
    }
    free(dic);
    return 0;
}

执行结果如下:
[root@localhost ~]# ./per 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
2 1 3 4
2 1 4 3
2 3 1 4
2 3 4 1
2 4 1 3
2 4 3 1
3 1 2 4
3 1 4 2
3 2 1 4
3 2 4 1
3 4 1 2
3 4 2 1
4 1 2 3
4 1 3 2
4 2 1 3
4 2 3 1
4 3 1 2
4 3 2 1


阅读(2984) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~