《數據結構與算法分析:C語言描述》習題1.1代碼及自己的想法

《數據結構與算法分析:C語言描述》習題1.1

大一狗放假在家自學點算法,編程渣,自己練習一下

————————————————————————————————————————(我是劃分線)

題目:編寫一個程序解決選擇問題。令k=N/2。畫出表格顯示你的程序對於N為不同值的運行時間。

       先來解釋一下什麼是“選擇問題”:設有一組N個數而要確定其中第k個最大者。

       書上第一章一開始就講了一種算法。

       再次闡述一下:

               先把前面k個數讀進一個數組中並(以遞減的順序)對其排序(排序後下標為[0]的為最大數,下標為[k-1]的為k個數中的最小數)。接著,將剩下的元素再逐個讀入。當新元素被讀到時,如果它小於數組中的第k個元素(下標為[k-1])則忽略,否則就將其放到數組中正確的位置上,同時將數組中的一個元素擠出數組。當算法結束時,位於第k個位置上的元素作為答案返回。

        一开始我是在main函數裡寫的,寫完後想想還是改寫成一個函數了。於是複製粘貼。。。

下面是我的代碼: 


#include <cstdio>
#include <ctime>
float ChooseK(const float A[], int n);

int main()
{
    double t;   //时间变量
    clock_t start,end; //用于计时
    int n, i;
    float result;
    
    printf("how many numbers you want to put in?\n");
    scanf("%d",&n);  //设置数的总数
    float arr[n/2]; //能盛放前k个数的数组
    for (i=0; i<n/2; i++)
        scanf("%f",&arr[i]);
    
    start=clock();  //计时开始
    result = ChooseK(arr, n);
    end=clock();  //计时结束
    
    t=((double)(end-start))/CLOCKS_PER_SEC;  //计算总时长
    printf("\n第k个最大的数字是%.2f\n", result);  //输出第k个最大者
    printf("The choosing program use %.7lf\n",t);  //输出用时
    
    return 0;
}



float ChooseK(const float A[], int n)
{
    int k = n/2;
    float arr[k];
    
    
    int i,j; //计数变量
    float temp;  //用于排序的交换
    
    for (i = 0; i < k ; i++)    //转移数组,方便数据交换
        arr[i] = A[i];
    
    for (i=1; i<k; i++)         //冒泡排序法对前面k个数进行降序排序
    {
        for (j=0; j<k-i; j++)
        {
            if(arr[j]<arr[j+1])
            {
                temp=arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
    
    float new;  //用于读取第k个以后的数字
    for ( k=1+n/2 ; k <= n ; k++)
    {
        scanf("%f",&new);
        if (new <= arr[n/2-1])
            continue;
        else
        {
            i=n/2-1;
            while (new>arr[i])    //找到new的正确位置
            {
                i--;
                if (i<0)
                    break;
            }
            int place = i+1;
            for (i=n/2-1; i > place; i--)  //删除的一定是最后一个数,然后依次向后移一位
                arr[i] = arr[i-1];
            arr[place] = new;
        }
    }
    
    return arr[n/2-1];     //返回数组中的第k个元素(数组中的最小数)
}


 


注意一下將new插入數組的過程。一開始我是從定位得到的arr[place]依次向後交換數值,這樣一來,每一次兩個數交換實際涉及三個變量,分別是arr[i],arr[i+1]和中間變量(現在已經改掉了,我發的代碼裡沒有這一變量),這樣可能會降低效率。=====於是~我後來改了一種,就是從後向前改動數。因為每一次插入一個新的數,被擠出數組的永遠是最後一個數,這樣就沒必要在向後移動其他數據的時候仍舊保留最後一個數,所以可以直接讓最後一個數賦值為倒數第二個數,倒數第二個數賦值為倒數第三個數,依次向前推進直到要插入新數據的位置處停止,然後將新的數據new放到指定位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值