将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是多少次? 要详细的解释
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是多少次? 要详细的解释相关的知识,希望对你有一定的参考价值。
最少是n次,最多是2n-1次,比较次数是当两个有序表的数据刚好是插空顺序的时候,比如:第一个序列是1,3,5,第二个序列是2,4,6,把第二个序列插入到第一个序列中,先把第二个序列中的第一个元素2和第一个序列依次比较,需要比较2次(和1,3比较),第二个元素4需要比较2次(和3,5比较,因为4比2大,2之前的元素都不用比较了),第三个元素6需要比较1次(只和5比较),所以最多需要比较5次。 参考技术A 答案是n次!当一个表的最小元素大于另一个表的最大元素时,比较次数最少!这种情况下,人的思维的第一反映是直接放一次不就好了!
可你要从计算机的角度去看,
例:01234和56789两个表元素,在计算机中要把5和01234都比一遍,才能知道怎么排! 参考技术B 首先这个题目没表达清楚,存储结构如果是单链表,则需要n次,顺序表则需要1次 参考技术C 最少当然是一了
一个有序表中最小的元素大于另一个的最大元素,一次即可本回答被提问者和网友采纳 参考技术D 对啊,就一次啊。
归并排序
简述
归并排序与基于交换、选择等排序的思想不一样,“归并”的含义是将两个或两个以上的有序表组合成一个新的有序表。
算法思想
假定序列有n个记录,则可以将其看成是n个有序子序列,每个子序列的长度为1,然后两两合并,得到(lceil n/2 ceil)个长度为2或1的有序序列;再两两归并,······如此重复,直到合并成一个长度为n的有序表为止,这种方法被称为2-路归并排序。
故我们将整个算法分为两个部分,一个部分用来进行序列的归并,一个部分用来递归排序。归并的算法需要一个缓存数组,用来临时存放归并过程中的数据,归并过程中,每次从两个子序列中选择一个较小(或较大)的数放入缓存数组,需要注意的是,最后可能有部分子序列有剩余的元素,需要单独把这部分剩余元素置入缓存数组,最后再把缓存数组中的序列复制到原数组则完成归并。递归排序的算法使用两个边界数来划分递归的区间,每一趟划分都把序列划分为两个子序列,再对两个子序列分别排序,排序结束后,把两个子序列归并到一个序列中,完成一趟递归排序。
我们在这里使用了一个缓存数组,如果缓存数组在每一趟递归排序中分配,则每次递归排序的算法中需要进行缓存数组内存的分配与释放,反复多次,会造成较大的时间开销,故我们采用一次动态分配的数组作为缓存数组。
算法性能分析
- 空间效率:辅助空间需要n个单元,故空间复杂度为(O(n))。
- 时间效率:每一趟归并的时间复杂度为(O(n)),共需要(lceil log_2n ceil)趟归并,因此时间复杂度为(O(nlog_2n))。
- 稳定性:merge函数不会改变大小相同的关键字相对次序,因此是一个稳定的算法。
C++实现
#include <iostream>
using namespace std;
// 归并两个子序列
void merge(int a[], int b[], int low, int mid, int high) {
int i = low, j = mid + 1, k = low;
while (i <= mid && j <= high) {
if (a[i] <= a[j]) // 选取较小的元素放入
b[k++] = a[i++];
else
b[k++] = a[j++];
}
// 处理剩余元素
while (i <= mid)
b[k++] = a[i++];
while (j <= high)
b[k++] = a[j++];
// 将缓存数组中的序列归还至原数组
for (int i = low; i <= high; ++i)
a[i] = b[i];
}
// 递归排序
void mSort(int a[], int b[], int low, int high) {
if (low < high) {
int mid = (low + high) / 2;
mSort(a, b, low, mid); // 递归排序子序列
mSort(a, b, mid + 1, high);
merge(a, b, low, mid, high); // 合并两个子序列
}
}
// 归并排序
void mergeSort(int a[], int n) {
int* b = new int[n]; // 分配辅助空间内存
mSort(a, b, 0, n - 1);
delete[] b;
}
int main() {
const int SIZE = 10;
int a[SIZE] = { 0 };
for (int i = 0; i < SIZE; ++i) {
a[i] = rand() % 10;
cout << a[i] << " ";
}
cout << "
";
mergeSort(a, SIZE);
for (auto elem : a)
cout << elem << " ";
return 0;
}
以上是关于将两个各有n个元素的有序表归并成一个有序表,其最少的比较次数是多少次? 要详细的解释的主要内容,如果未能解决你的问题,请参考以下文章