数组合并假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数-C-icoding-排序-数据结构

数组合并
假设有 n 个长度为 k 的已排好序(升序)的数组,请设计数据结构和算法,
将这 n 个数组合并到一个数组,且各元素按升序排列。即实现函数:

 void merge_arrays(const int* arr, int n, int k, int* output);


其中 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 变化为int
	for(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);
	} 
//最后复制到output
	for(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;
}

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风起风里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值