數據結構與算法 試題2.7 - 生成前N個天然數的一個隨機置換

數據結構與算法 2.7

習題2.7

假設須要生成前N個天然數的一個隨機置換。例如,{3,4,1,5,2}和{5,2,3,1,4}就是合法的置換,但{5,4,1,2,1}卻不是,由於數1出現了兩次而數3卻沒有。 這個程序經常使用語模擬一些算法。咱們假設存在一個隨機數生成器RandInt(i,j),它以相同的機率生成i和j之間的一個整數。下面是三個算法:php

  1. 以下填入從A[0]到A[N-1]的數組A;爲了填入A[i],生成隨機數直到它不一樣於生成的A[0],A[1]......A[i-1]時,在填入A[i]
  2. 同算法(1),可是要保存一個附加數組,稱之爲Used(用過的)數組。當一個隨機數Ran最初被放入數組A的時候,置Used[Ran]=1。這就是說,當一個隨機數填入A[i]時能夠進一步測試是否該隨機數已經被使用,而不是像第一個算法那樣(可能)進行i步測試。
  3. 填寫該數組使得A[i]=i+1。而後:
    for (i = 1; i < N; i++) {  
        Swap(&A[i], &A[RandInt(0, i)]);  
    }
  • a. 證實這三個算法都生成合法的置換,而且全部的置換都是等可能的。
  • b. 對每個算法給出你可以獲得的儘量準確的指望的運行時間分析。
  • c. 分別寫出程序來執行每一個算法10次,得出一個好的平均值。對於N=250, 500, 1000, 2000運行程序1;對於N=2500,5000,10000,20000,40000,80000運行程序2;對N=10000,20000,40000,80000,160000,320000,640000運行程序3。
  • d. 將實際的運行時間與你的分析時間進行比較
  • e. 每一個算法的最壞情形的運行時間是什麼?

參考資料

  1. 返回數組
  2. 數組做爲參數
  3. 隨機數
  4. PHP隨機數函數-頭文件
  5. PHP隨機數函數-源文件

頭文件

// 隨機置換方法一
extern void RandRangOne(int[], int);
// 隨機置換方法二
extern void RandRangTwo(int[], int);

源文件

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

#include <time.h>

/**
 * 產生[min, max]之間的一個隨機數
 * 注:參考PHP隨機數生成的處理
 * @param min
 * @param max
 * @return 
 */
int RandInt(int min, int max) {
    srand((unsigned int)(time(0) * getpid()) ^ (unsigned int)(1000000.0));
    return min + (int)((double)((double)(max) - (min) + 1.0) * ((rand()) / ((RAND_MAX) + 1.0)));
}

/**
 * 隨機置換算法一
 * @param a
 * @param size
 */
void RandRangOne(int a[], int size) {
    int i;
    for (i = 0; i < size; i++) {
        while (1) {
            int rand = RandInt(1, size);
            int flag = 0;

            int j;
            for (j = 0; j < i; j++) {
                if (a[j] == rand) {
                    flag = 1;
                    break;
                }
            }

            if (flag) {
                continue;
            }

            a[i] = rand;
            break;
        }
    }
}

/**
 * 隨機置換算法二
 * @param a
 * @param size
 */
void RandRangTwo(int a[], int size) {
    int used[size], i;
    for (i = 0; i < size; i++) {
        while (1) {
            int rand = RandInt(1, size);

            if (used[rand] == 1) {
                continue;
            }

            a[i] = rand;
            used[rand] = 1;
            break;
        }
    }
}

調用示例

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

#include "ext/s8/fun.h"

int main(int argc, char** argv) {
    int a[10];
    RandRangTwo(a, 10);

    int i;
    for(i = 0; i < 10; i++) {
        printf("%d\n", a[i]);
    }
    return (EXIT_SUCCESS);
}
相關文章
相關標籤/搜索