改变C中数组的大小

时间:2016-02-03 10:53:30

标签: c arrays sorting

我编写了一个生成随机数组的程序,并使用insert和quicksort算法对其进行排序。该程序还测量每个函数的运行时间。数组的大小在前导码中定义为参数化宏L。我的问题是:

  

如何在一次执行中使用各种大小的数组测试两种排序算法?

我希望我的程序在一次执行中对大小为L=10, 100, 1000, 500010000的数组进行排序。我的程序代码详述如下。

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

//Random Array Length
#define MAX 100
#define L 10

void naive_sort(int[]);
void smarter_sort(int[],int,int);
void swap(int[],int,int);
int choose_piv(int[],int,int);

int main(){
    int i, a[L], b[L];
    clock_t tic, toc;

    //Generate an array of random numbers
    for(i=0; i<L; i++)
        a[i]= rand() % (MAX+1);

    //Define b identical to a for fair comparison
    for(i=0; i<L; i++)
        b[i]=a[i];

    //Unsorted Array
    printf("\nUnsorted array:   ");
    for(i=0; i<L; i++)
            printf("%d    ", a[i]);

    //Insertion Sort (1e)
    tic = clock();
    naive_sort(a);
    printf("\nInsertion Sort:   ");
            for(i=0; i<L; i++)
                printf("%d    ", a[i]);
    toc = clock();
    printf("  (Runtime: %f seconds)\n", (double)(toc-tic)/CLOCKS_PER_SEC);

    //Quicksort (1f)
    tic = clock();
    smarter_sort(b,0,L-1);
    printf("Quicksort:        ");
            for(i=0; i<L; i++)
                printf("%d    ", b[i]);
    toc = clock();
   printf("  (Runtime: %f seconds)\n", (double)(toc-tic)/CLOCKS_PER_SEC);

   return 0;
}

void naive_sort(int a[]){
    int i, j, t;
    for(i=1; i < L; i++){
        t=a[i];
        j=i-1;
        while((t < a[j]) && (j >= 0)){
            a[j+1] = a[j];
            j--;
        }
        a[j+1]=t;
    }
}

void smarter_sort(int a[], int l, int r){
    if(r > l){
        int piv = choose_piv(a, l, r);
        smarter_sort(a, l, piv-1);
        smarter_sort(a, piv+1, r);
    }
}

void swap(int a[], int i, int j){
    int t=a[i];
    a[i]=a[j];
    a[j]=t;
}

int choose_piv(int a[], int l, int r){
    int pL = l, pR = r;
    int piv = l;
    while (pL < pR){
        while(a[pL] < a[piv])
            pL++;
        while(a[pR] > a[piv])
            pR--;
        if(pL < pR)
            swap(a, pL, pR);
    }
    swap(a, piv, pR);
    return pR;
}

我将不胜感激。

编辑:我按照建议修改了代码,它适用于较小的值。但对于快速排序案例L=100及其后,我没有得到任何输出:

enter image description here

正如您所看到的,我得到的少数输出为零。代码有什么问题?

/*
 * Task 1, question h
 */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

//Random Array Length
#define MAX 100

void perf_routine(int);
void naive_sort(int[],int);
void smarter_sort(int[],int,int);
void swap(int[],int,int);
int choose_piv(int[],int,int);

int main(){
    perf_routine(10);
    perf_routine(100);
    perf_routine(1000);
    perf_routine(5000);
    perf_routine(10000);
   return 0;
}

void perf_routine(int L){
    int i, a[L], b[L];
        clock_t tic, toc;

        printf("Arrays of Length %d:\n", L);

        //Generate an array of random numbers
        for(i=0; i<L; i++)
            a[i]= rand() % (MAX+1);

        //Define b identical to a for fair comparison
        for(i=0; i<L; i++)
            b[i]=a[i];

        //Insertion Sort (1e)
        tic = clock();
        naive_sort(a, L);
        toc = clock();
        printf("Insertion Sort Runtime: %f seconds\n", (double)(toc-tic)/CLOCKS_PER_SEC);

        //Quicksort (1f)
        tic = clock();
        smarter_sort(b,0,L-1);
        toc = clock();
       printf("Quicksort Runtime: %f seconds\n", (double)(toc-tic)/CLOCKS_PER_SEC);
}

void naive_sort(int a[], int L){
    int i, j, t;
    for(i=1; i < L; i++){
        t=a[i];
        j=i-1;
        while((t < a[j]) && (j >= 0)){
            a[j+1] = a[j];
            j--;
        }
        a[j+1]=t;
    }
}

void smarter_sort(int a[], int l, int r){
    if(r > l){
        int piv = choose_piv(a, l, r);
        smarter_sort(a, l, piv-1);
        smarter_sort(a, piv+1, r);
    }
}

void swap(int a[], int i, int j){
    int t=a[i];
    a[i]=a[j];
    a[j]=t;
}

int choose_piv(int a[], int l, int r){
    int pL = l, pR = r;
    int piv = l;
    while (pL < pR){
        while(a[pL] < a[piv])
            pL++;
        while(a[pR] > a[piv])
            pR--;
        if(pL < pR)
            swap(a, pL, pR);
    }
    swap(a, piv, pR);
    return pR;
}

2 个答案:

答案 0 :(得分:4)

我会在每个函数中给出参数中数组的长度,并确保不要尝试到达数组之外的元素,例如swap将变为:

int swap(int *a, int length, int i, int j)
{
    if(i>=length || j>=length)
        return -1;
    int t=a[i];
    a[i]=a[j];
    a[j]=t;
    return 0;
}

另请注意,返回-1或0表示失败。将其应用于其余代码,您将拥有可应用于任何阵列的内容。

答案 1 :(得分:3)

当数组传递给函数时,它们作为(或“衰减到”)指针传递给它们的第一个元素。无法知道数组的大小。

因此,将实际长度作为附加参数传递给函数是很常见的。如果下面有三个不同大小的数组的天真排序示例。

当然,必须注意保持阵列和长度同步。传递太大的长度可能会导致未定义的行为。例如,在下面的示例中调用fill(tiny, LARGE)可能会导致灾难。

(旁白:数组可能具有最大长度或容量以及实际长度。例如,如果要从文件中读取最多十个数字,则必须传递长度为10的数组,但如果只有四个数字读取,你在这里处理两个额外的参数:可能的数组长度,10,实际长度,4。但这不是这种情况。)

嗯,这就是。所有三个数组函数都具有相同的签名:它们采用数组及其长度。

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

void sort(int a[], size_t len)
{
    size_t i, j;

    for (i = 1; i < len; i++) {
        int t = a[i];

        j = i - 1;

        while (j >= 0 && t < a[j]) {
            a[j + 1] = a[j];
            j--;
        }

        a[j + 1] = t;
    }
}

void fill(int a[], size_t len)
{
    size_t i;

    for (i = 0; i < len; i++) {
        a[i] = rand() / (1.0 + RAND_MAX) * 100;
    }
}

void print(int a[], size_t len)
{
    size_t i;

    for (i = 0; i < len; i++) {
        if (i) printf(", ");
        printf("%d", a[i]);
    }

    puts("");
}

#define TINY 3
#define MEDIUM 10
#define LARGE 15

int main(void)
{
    int tiny[TINY];
    int medium[MEDIUM];
    int large[LARGE];

    srand(time(NULL));

    fill(tiny, TINY);
    fill(medium, MEDIUM);
    fill(large, LARGE);

    print(tiny, TINY);
    print(medium, MEDIUM);
    print(large, LARGE);

    sort(tiny, TINY);
    sort(medium, MEDIUM);
    sort(large, LARGE);

    print(tiny, TINY);
    print(medium, MEDIUM);
    print(large, LARGE);

    return 0;
}