int main (int argc, char* argv[]) { //create a pointer, which will be used to store the array int *A; //check if the user ran the program correctly if (argc < 2) { fprintf(stderr, "Usage: mean_median file1 [file2 ...]\n"); } //if the program is run correctly argv[1] will be the first //command line argument. ie name of the input file char *file = argv[1]; //open file for reading FILE *fp = fopen(file, "rb"); if (fp == NULL) return 1; //call read_array function which will allocate space for A //read the file and put the numbers in array A //the read_array function must return the size of the array int n = read_array(fp, &A); if (n < 0) { return 1; } //print array A of size n print_array(A, n); //sort select_sort(A, n); //print again print_array(A, n); //calculate mean and median of array A double mean = mean_array(A, n); double med = median_array(A, n); //print results printf("mean = %f med = %f\n", mean, med); //cleanup free(A); fclose(fp); return 0; }
NODE* build_tree_array(double **point_array, double **storage, int N, int K, int depth){ //This builds a k-dimensional tree from the point_array 2d array. int dim, m=0, i; //counters int approx_limit = 10000; //if more points than this, find approximate median int approx_N = 1000; //use this many points to find approximate median NODE *node = NULL; //node that we're finding double **larray, **lstore; // array to send to left child double **rarray, **rstore;// array to send to right child //printf("In 'build_tree_array', depth = %d:\n", depth); //NULL_CHECK(point_array, "", "point_array", i, N); if(N==0){ // if no data, return return(NULL); } //NULL_CHECK(point_array, "", "point_array", i, N); //puts("Allocating memory to node"); //printf("node: %u, node->left: %u\n", node, node->left); node = (NODE*) malloc( (int)sizeof(NODE)); // allocate the memory for the node MALLOC_CHECK(node); //puts("Allocation successful"); init_node(node); //initialise the node //NULL_CHECK(point_array, "", "point_array", i, N); dim = depth % K; // find which dimension we're looking at //puts("Finding median of 'point_array'."); if( (N > 1) && (N < approx_limit) ){ // if 1<N<approx_limit, sort them and find median, this gives an exactly balanced tree qsort_nd2(point_array, storage, N, K, dim); m = median_array(point_array, N, dim); } else if(N >= approx_limit){ //if N<approx_limit, find an approximate value of the median, this gives pretty well balanced trees double **approx_array, **approx_store; //pointers //puts("N is larger than approx_limit, allocating space for approximation arrays"); approx_array = (double**) malloc( (int)sizeof(double*)*approx_N ); //allocate stuff approx_store = (double**) malloc( (int)sizeof(double*)*approx_N ); srand(time(NULL)); //seed the random number generator //puts("seeding approximate array"); for(i=0;i<approx_N;i++){ int j = rand() % N; //make sure that j is a random number between 0 and N-1 approx_array[i] = point_array[j]; //populate the approximation array } //puts("sort reduced array"); qsort_nd2(approx_array, approx_store, approx_N, K, dim); //sort our reduced array //puts("find median of reduced array"); m = median_array(approx_array, approx_N, dim); //find it's median //puts("order the real array to be split up: lt, median, gt."); m = order_lt_gt(point_array, storage, approx_array[m], N, K, dim); //change order of 'point_array' to {[<m], m, [>m]} //and tell us 'm' free(approx_array); //free stuff and set to NULL approx_array = NULL; free(approx_store); approx_store = NULL; //continue as normal } //puts("Found median"); node->val = point_array[m]; //store the value of the median data point in this node //puts("Finding left array"); larray = point_array; //left array is from the beginning, to the value before the median lstore = storage; //similarly with storage array node->left = build_tree_array(larray, lstore, m, K, depth+1); // recurse //puts("Finding right array"); rarray = &(point_array[m+1]); // right array is from the value after the median to the end rstore = &(storage[m+1]); //similarly with storage node->right = build_tree_array(rarray, rstore, (N-(m+1)), K, depth+1); // recurse return(node); }