码迷,mamicode.com
首页 > 编程语言 > 详细

[C++]封装排序二叉树&随机数生成(c++11)

时间:2016-05-12 21:56:30      阅读:493      评论:0      收藏:0      [点我收藏+]

标签:

封装排序二叉树&随机数生成(c++11)

本文,我尝试着把排序二叉树封装为一个模板类,并且用C++11给出的随机数生成函数来对这个类进行测试。

排序二叉树封装

这个二叉树的特征是,左子数的值肯定比父节点小,右子树的值肯定比父节点的大。要求大家按照这个结构特征去构建二叉树,最后中序遍历输出就是我们要求的升序输出。

我们可以根据具体的要求来完成对排序二叉树的构建,可以用一个bool函数来区别不同排序顺序,默认是升序。紧接着用递归来不断地insert新的节点。最后用中序遍历就可以得到我们需要的排序结果。如果想要改变visit输出方式,要也可以设定一个函数指针。不过因为封装性,还需要在类里面增加对Node的内部访问。

//
//  main.cpp
//  排序
//
//  Created by 颜泽鑫 on 5/9/16.
//  Copyright ? 2016 颜泽鑫. All rights reserved.
//

#include <iostream>
#include <vector>
#include <random>
#include <time.h>
#include <algorithm>
#include <iomanip>
using namespace std;
template <typename T>
bool cmps(T a, T b);
template <typename T>
class BinaryTree {
public:
    struct Node {
        T value;
        Node* left;
        Node* right;
        Node(T vals = 0, Node* lefts = NULL, Node* rights = NULL) : value(vals), left(lefts), right(rights) {
        }
    };
    BinaryTree(const std::vector<T>& orig, bool (*cmp)(T a, T b) = cmps<T>);
    ~BinaryTree();
    void print();
private:
    Node* root;
    void insert(Node* root, T value, bool (*cmp)(T a, T b));
    void clear(Node* temp);
    void visit(Node* root);
};
template <typename T>
bool cmps(T a, T b) {
    if (a <= b) {
        return true;
    } else {
        return false;
    }
}

template <typename T>
void BinaryTree<T>::insert(BinaryTree::Node *root, T value, bool (*cmp)(T a, T b)) {
    if (cmp(value, root->value)) {
        if (root->left == NULL) {
            Node* temp = new Node(value);
            root->left = temp;
        } else {
            insert(root->left, value, cmp);
        }
    } else {
        if (root->right == NULL) {
            Node* temp = new Node(value);
            root->right = temp;
        } else {
            insert(root->right, value, cmp);
        }
    }
}

template <typename T>
BinaryTree<T>::BinaryTree(const std::vector<T>& orig, bool (*cmp)(T a, T b)) {
    root = new Node(orig[0]);
    for (int i = 1; i != orig.size(); i++) {
        insert(root, orig[i], cmp);
    }
}
template <typename T>
void BinaryTree<T>::clear(Node* root) {
    if (root != NULL) {
        clear(root->left);
        clear(root->right);
        delete root;
    }
}
template <typename T>
BinaryTree<T>::~BinaryTree() {
    clear(root);
}
template <typename T>
void BinaryTree<T>::visit(BinaryTree::Node *root) {
    if (root != NULL) {
        visit(root->left);
        std::cout << root->value << " ";
        visit(root->right);
    }
}
template <typename T>
void BinaryTree<T>::print() {
    visit(root);
}

测试函数:

int main() {
    int range;
    std::cin >> range;
    int total_num = range;
    std::vector<double> input;
    std::random_device ram;
    std::uniform_real_distribution<> dis(1, range);
    double value = 0;
    while (total_num--) {
        value = dis(ram);
        input.push_back(value);
    }
    BinaryTree<double> tree(input);
    tree.print();
    return 0;
}

随机数生成类

接下来我们讨论随机数的生成方法。

在C++11中给出了一个新的特性来完成随机数的生成。

1. random_device

标准库提供了一个非确定性随机数生成设备.在Linux的实现中,是读取/dev/urandom设备;Windows的实现居然是用rand_s,在这里强烈谴责一下.

random_device提供()操作符,用来返回一个min()到max()之间的一个数字.如果是Linux(Unix Like或者Unix)下,都可以使用这个来产生高质量的随机数,可以理解为真随机数.

#include <iostream>
#include <random>
int main() {
  std::random_device rd;
  for(int n=0; n<20000; ++n)
    std::cout << rd() << std::endl;
  return 0; 
}

2. random number engine

标准把随机数抽象成随机数引擎分布两部分.引擎用来产生随机数,分布产生特定分布的随机数(比如平均分布,正太分布等).

标准提供三种常用的引
擎:linear_congruential_engine,mersenne_twister_engine和subtract_with_carry_engine.第一种是线性同余算法,第二种是梅森旋转算法,第三种带进位的线性同余算法.第一种是最常用的,而且速度也是非常快的; 第二种号称是最好的伪随机数生成器;第三种没用过….

随机数引擎接受一个整形参数当作种子,不提供的话,会使用默认值. 推荐使用random_device来产生一个随机数当作种子.(windows下爱咋整咋整,谁叫windows的random_device是调用rand_s)

#include <iostream>
#include <random>

int main()
{
  std::random_device rd;
  std::mt19937 mt(rd());
  for(int n = 0; n < 10; n++)
    std::cout << mt() << std::endl;
  return 0;
}

3. random number distributions

标准提供各种各样的分布,不过我们经常用的比较少,比如平均分布,正太分布…使用也很简单

//平均分布
#include <random>
#include <iostream>
int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> dis(1, 6);
    for(int n=0; n<10; ++n)
        std::cout << dis(gen) << ‘ ‘;
    std::cout << ‘\n‘;
}
//正态分布
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
#include <cmath>
int main() {
    std::random_device rd;
    std::mt19937 gen(rd());

    // values near the mean are the most likely
    // standard deviation affects the dispersion of generated values from the mean
    std::normal_distribution<> d(5,2);

    std::map<int, int> hist;
    for(int n=0; n<10000; ++n) {
        ++hist[std::round(d(gen))];
    }
    for(auto p : hist) {
        std::cout << std::fixed << std::setprecision(1) << std::setw(2)
                  << p.first << ‘ ‘ << std::string(p.second/200, ‘*‘) << ‘\n‘;
    }
}

[C++]封装排序二叉树&随机数生成(c++11)

标签:

原文地址:http://blog.csdn.net/stary_yan/article/details/51352446

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!