算法笔记 //08_最优合并问题

★问题描述:

    给定 k 个排好序的序列 s1,s2,...,sk,用 2 路合并算法将这 k 个序列合并成一个序列。
    假设所采用的 2 路合并算法合并 2 个长度分别为 m 和 n 的序列需要 m + n - 1 次比较。
    试设计一个算法确定合并这个序列的最优合并顺序,使所需的总比较次数最少。
    为了进行比较,还需要确定合并这个序列的最差合并顺序,使所需的总比较次数最多。

★算法思想

1.给定的所有序列已经排好了顺序,无需再进行排列;
2.所采用的 2 路合并算法合并两个序列所需的比较次数已经给出,直接调用;
3.既然是求最优和最差,那也就是考虑两种极端情况,分析结果如下:
  ① 最差合并顺序:总是最长的两个序列先合并
  ② 最优合并顺序:总是最短的两个序列先合并

★ C++代码如下(VC++ 6.0实现,学校机房无 VS)

//写得很麻烦,希望有改良版私信我。。。。谢谢

#include "stdafx.h"

#include
#include
using namespace std;

//最优合并方法次数
int min(int *a,int n) {

    int number = n, result_min = 0;
    int *s = new int[n];
    s = a;
    int i, j, temp;

    while (number > 1) {
        for (i = 0; i < number; i ++) {
            for (j = i + 1; j < number; j ++) {
                if (s[i] > s[j]) 
                {
                    temp = s[i]; 
                    s[i] = s[j]; 
                    s[j] = temp;
                }
            }
        }
        s[0] = s[0] + s[1];
        result_min += s[0] - 1; // m + n - 1
        number --;
        for (i = 1; i < number; i ++)
            s[i] = s[i + 1];
    }   
    return result_min;  
}

//最差合并方法次数
int max(int *b,int n) {

    int number = n, result_max = 0;
    int *s = new int[n];
    s = b;
    int i, j, temp;

    while (number > 1) {
        for (i = 0; i < number; i ++) {
            for (j = i + 1; j < number; j ++) {
                if (s[i] < s[j])
                { 
                  temp = s[i]; 
                  s[i] = s[j]; 
                  s[j] = temp; 
                }
            }
        }
        s[0] = s[0] + s[1];
        result_max += s[0] - 1;
        number --;
        for (i = 1; i < number; i ++)
            s[i] = s[i + 1];
    }
    return result_max;
}

//主函数
void main() {

    while(1)
    {
        int q;
        cout << "Please input the number of sequences: " << endl;  // 请求用户输入序列的个数
        cin >> q;

        cout << "Please input the size of each sequence: " << endl;
        int *a = new int[q];  // 动态分配数组大小,存储用户输入的每个序列的大小数值
        for (int i = 0; i < q; i++)
        { cin >> a[i]; }    // 读取用户输入的每个序列的大小数值
        cout << "最优算法次数为: " << min(a,q) << endl;
        cout << "_____________________________________________________________" << endl;

        int p;
        cout << "Please input the number of sequences: " << endl;  // 请求用户输入序列的个数
        cin >> p;

        cout << "Please input the size of each sequence: " << endl;
        int *b = new int[p];  // 动态分配数组大小,存储用户输入的每个序列的大小数值
        for (int j = 0; j < p; j++)
        { cin >> b[j]; }    // 读取用户输入的每个序列的大小数值
        cout << "最差算法次数为: " << max(b,p) << endl;
        cout << "_____________________________________________________________" << endl;
    }
    delete[] a;
    delete[] b;
    system("pause");
}

你可能感兴趣的:(算法&数据结构の笔记)