算法导论2nd 9.1-1

原创
2019/05/07 01:19
阅读数 438

为方便处理,设输入规模n为2的次方。

算法:将数组划分成对,比较选出最小的元素,这些选出的最小元素再次划分成对,再比较选出最小元素,重复这个过程,直到找出整个数组的最小元素。这个过程是一个自底向上构造二叉树的过程,在构造的过程中记录最小元素的生成路径,回溯路径上的兄弟结点即可找出第二小的元素。

构造二叉树找出最小元素比较n-1次,回溯找出第二小元素比较lgn -1次,所以总共比较n+lgn-2次。

#include <iostream>
#include <vector>

struct Node
{
    int key;
    std::size_t prev; // 上一层的结点索引
    Node(int x, int i) : key(x), prev(i) {}
};

std::size_t getsecond(const std::vector<Node> &floor, int &second)
{
    if (floor.size() == 1)
        return floor.front().prev;
    std::vector<Node> nextFloor;
    for (std::size_t i = 0; i < floor.size(); i += 2)
    {
        if (floor[i].key < floor[i+1].key) // 生成二叉树找出最小元素的比较
            nextFloor.emplace_back(floor[i].key, i);
        else
            nextFloor.emplace_back(floor[i+1].key, i+1);
    }
    std::size_t path = getsecond(nextFloor, second); // 最小元素的路径索引
    std::size_t other = path / 2 * 2 + ((path + 1) % 2); // 最小元素的兄弟索引
    second = floor[other].key < second ? floor[other].key : second; // 递归回溯找出第二小元素的比较
    return path;
}

int main()
{
    int a[] = {1, 8, 3, 4, 5, 6, 7, 2};
    std::vector<Node> nodes;
    for (int t: a)
        nodes.emplace_back(t, -1);
    int second = 0x7fffffff;
    getsecond(nodes, second);
    std::cout << "second smallest: " << second << std::endl;
    return 0;
}

 

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部