习题2.8 输出全排列(20 分)

习题2.8 输出全排列(20 分)

请编写程序输出前n个正整数的全排列(n<10),并通过9个测试用例(即n从1到9)观察n逐步增大时程序的运行时间。

输入格式:

输入给出正整数n<10)。

输出格式:

输出1到n的全排列。每种排列占一行,数字间无空格。排列的输出顺序为字典序,即序列a1,a2,,an排在序列b1,b2,,bn之前,如果存在k使得a1=b1,,ak=bk 并且 ak+1<bk+1

输入样例:

3

输出样例:

123
132
213
231
312
321
#include <stdio.h>
#include <stdlib.h>

typedef int ElementType;

void quicksort( ElementType A[], int l, int r);
void swapElement(ElementType *a, ElementType *b);
void dictPrem(ElementType ary[], int len);
void showarray(ElementType a[], int len);

void swapElement(ElementType *a, ElementType *b)
{
    ElementType temp = 0;
    temp = *a;
    *a = *b;
    *b = temp;

}
void quicksort( ElementType A[], int l, int r)
{
    ElementType tmp;
    int i, j;

    if(l < r)
    {
        i = l;
        j = r;
        tmp = A[i];
        while(i < j)
        {
            while(A[j]>tmp && i<j) //一定要i<j,因为下面j--改变了j的值,没有这个判定,无法跳过A[j]大于tmp不用改变j值的情况
                j--;               //由右往左寻找,遇到A[j]>tmp则跳过,寻找下一个
            if(i<j)
            {
                A[i] = A[j];
                i++;
            }
            while(A[i]<tmp && i<j) //改变这里的A[i]<tmp小于的符号,同时改变42行A[j]>tmp的大于符号,可以改为由大到小排列
                 i++;
            if(i<j)
            {
                A[j] = A[i];
                j--;
            }
            //showarray(A, r+1);
            //printf("\n***************************\n");
        }
        /**< 如果r == l,下面的语句不会执行,这也是迭代停止的条件 */
        A[i] = tmp;
        quicksort(A, l, i-1);
        quicksort(A, i+1, r);
    }
}

void showarray(ElementType a[], int len)
{
    int j;
    for(j=0; j<len; j++)
        {
             printf("%d ", a[j]);
        }
    printf("\n");
}

void dictPrem(ElementType ary[], int len)
{
    int cnt, i, j, a, b;
    for(i=1, cnt=1; i<=len; i++)
    {
        cnt *= i;
    }
    while(cnt--)
    {
        showarray( ary, len);
        for(i=len-1; i>0; i--)
        {
            if(ary[i-1]<ary[i])
            {
                a = i-1;
                //printf("a=%d\t", a);
                break;
            }
        }
        for(i=len-1; i>a; i--)
        {
            if(ary[i]>ary[a])
            {
                b = i;
                //printf("b=%d\n", b);
                break;
            }
        }
        swapElement(&ary[a], &ary[b]);
        quicksort(ary, a+1, len-1);
    }
}

int main()
{
    int n, i;
    scanf("%d", &n);
    ElementType list[n];
    for(i=0; i<n; i++)
    {
        list[i] = i+1;
    }
    dictPrem(list, n);
    system("pause");
}

提交时间 状态 分数 题目 编译器 耗时 用户
2018/1/3 11:05:10 答案正确 20 习题2.8 C (gcc) 549 ms Roy
测试点 提示 结果 耗时 内存
0 1 答案正确 2 ms 224KB
1 2 答案正确 2 ms 256KB
2 3 答案正确 2 ms 136KB
3 4 答案正确 2 ms 228KB
4 5 答案正确 2 ms 128KB
5 6 答案正确 3 ms 256KB
6 7 答案正确 8 ms 360KB
7 8 答案正确 57 ms 620KB
8 9 答案正确 549 ms 3876KB


不知道是状态不好,还是怎样,这题做了差不多1天,那个全排列至今没有弄懂。字典排序相对容易理解,可以看这篇博客字典序算法



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值