数组合并假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数-C-icoding-排序-数据结构
生活随笔
收集整理的這篇文章主要介紹了
数组合并假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数-C-icoding-排序-数据结构
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
數組合并
假設有 n 個長度為 k 的已排好序(升序)的數組,請設計數據結構和算法,
將這 n 個數組合并到一個數組,且各元素按升序排列。即實現函數:
其中 arr 為按行優先保存的 n 個長度都為 k 的數組,output 為合并后的按升序排列的數組,大小為 n×k。
時間要求(評分規則),當 n > k 時:
滿分:時間復雜度不超過 O(n×k×log(n))
75分:時間復雜度不超過 O(n×k×log(n)×k)
59分:其它,如:時間復雜度為 O(n2×k2) 時。
參考代碼如下:(別抄理解下哈哈)
#include<stdio.h> #include<stdlib.h> //建立大根堆(大的在上面) void build_bigroot(int *a, int i, int size){ //參數說明:a傳入的數組,i待排序元素開始位置,size數組元素個數(長度)int j, s;//j是i的孩子指針,s暫存排序的元素//不設監視哨,所以從'0'(i)開始排序,孩子為2*i+1 j = 2 * i + 1;s = a[i];while(j < size){//不可以取等哈 ,0開始的//存在右子樹并且右子樹更大,那么篩選右子樹 if(j + 1 < size && a[j+1] > a[j])j++; if(s >= a[j])break;else{//如果大的記錄在下,那么上浮 a[i] = a[j];i = j;j = 2 * i + 1;} }//最后把篩選完成后的數據放在合適位置a[i] = s; }void merge_arrays(const int *arr, int n, int k, int* output){//說明一下arr為const int類型,不能改動,所以只好浪費時空復制出來在變動int i, size, x;size = n * k;int a[size];//const int 變化為intfor(i= 0; i < size; i++)a[i] = arr[i];//大堆化for(i = size / 2 -1; i >= 0; i--)build_bigroot(a, i , size);//正式堆排, 前提是大堆for(i = size - 1; i >=1; i--){x = a[0];a[0] = a[i];a[i] = x;build_bigroot(a, 0, i);} //最后復制到outputfor(i = 0; i < size; i++)output[i] = a[i]; }?其實我不明白的是為什么不用輔助數組a,直接復制到output里面不行.......
以下不是參考代碼!
請教大佬!!!
另外,我最初的考慮是希爾排序
主函數能運行, 但是寫為子函數就有問題了:
?主函數如下:
//icoding測試貌似只有幾十分 #include<stdio.h> #include<stdlib.h> void merge_arrays(const int *arr, int row, int col, int* output){int i, j, x;int d[10]; int delta;for(i = 1; i < 10; i++)d[i] = 0;for(i = 0; i < col * row; i++)output[i] = arr[i];x = col; for(i = 0; x; i++, x=x/ 2)d[i] = x;for(i = 0, delta = d[i]; d[i]!= 0; delta = d[i], i++){for(i = delta; i < row * col; i++){if(output[i] < output[i - delta]){//如果前面的元素更大,就需要改變元素的位置 x = output[i];for(j = i - delta; j >= 0 && output[j] > x; j -= delta)output[j + delta] = output[j]; // 大的復制到后面的對應位置output[j + delta] = x; }} }for(i = 1; i < row * col; i++){x = output[i];j = i -1;while(x < output[j]){output[j + 1] = output[j];j = j -1;output[j+1] = x;}} }?子函數類型的:
#include<stdio.h> #include<stdlib.h> void shellinsert(int *output, int length, int delta){//arr 待排序數組, 內部元素可以看為row個長度為col的升序數組以此首尾連接//length為數組整體總長度, delta為增量int i, j;int x;for(i = delta; i < length; i++){if(output[i] < output[i - delta]){//如果前面的元素更大,就需要改變元素的位置 x = output[i];for(j = i - delta; j >= 0 && output[j] > x; j -= delta)output[j + delta] = output[j]; // 大的復制到后面的對應位置output[j + delta] = x; }}for(i=0; i<9 ;i++)printf("%d ", output[i]);printf("\n"); } void merge_arrays(const int *arr, int row, int col, int* output){ //數組長度為col, 總共有row個升序數組int i;int d[10];for(i = 0; i < col * row; i++)output[i] = arr[i];for(i = 0; col; i++, col /= 2)d[i] = col;for(i = 0; d[i]; i++)shellinsert(output, row * col, d[i]); }int main(){int a[9] = {12, 15, 16, 1, 2, 3, 4, 8, 10};int output[9];merge_arrays(a, 3, 3, output);int i = 0;for(;i < 9; i++)printf("%d ", output[i]);return 0; }?
總結
以上是生活随笔為你收集整理的数组合并假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数-C-icoding-排序-数据结构的全部內容,希望文章能夠幫你解決所遇到的問題。