[C++]封装排序二叉树&随机数生成(c++11)
来源:互联网 发布:达内编程培训 编辑:程序博客网 时间:2024/05/01 04:44
封装排序二叉树&随机数生成(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)
- C/C++:随机数生成
- 随机数生成c++(转)
- objective-c 生成随机数
- C/C++生成随机数
- C语言生成随机数
- c生成随机数
- C随机数生成函数
- C语言生成随机数
- c 生成随机数
- C/C++随机数生成
- C/C++生成随机数
- C语言生成随机数
- C语言生成随机数
- C语言生成随机数
- c随机数生成
- c/c++生成随机数
- C/C++ 生成随机数
- TensorFlow学习笔记之二——安装和运行
- java文件操作
- $("linkage").jqzoom({options})图片放大插件
- VideoView的事件监听
- YY4-带人的技术(第五章)笔记-__XwD__-V1
- [C++]封装排序二叉树&随机数生成(c++11)
- MD5加密的使用
- 关于Android studio .9图的问题
- 设计模式详解(总纲)
- YY4-带人的技术(第六章)笔记-__XwD__-V1
- 实习日志-mysql-涉及多表的条件查询
- ‘inet_pton’ was not declared in this scope
- YY4-带人的技术(第七章)笔记-__XwD__-V1
- 系统找不到文件 BIN_DIRECTORY\..\conf\sbtconfig.txt