对于大量的输入数据,链表的线性访问时间太慢,不宜使用——《数据结构与算法分析——C 语言描述》 p 65

  对于大量的输入数据,适合用树结构,大部分操作都是 O( log N )。

  二叉树

  1. 实现

  节点定义

template<typename T>
struct Node
{
Node(T v) : val(v), left(nullptr), right(nullptr) {}; T val;
struct Node *left;
struct Node *right;
};

  构建树并添加节点

  按照如图的树构建

Node<int> *root = new Node<int>(); //根节点

root->left = new Node<int>(); //根节点的左子树
root->left->right = new Node<int>(); root->right = new Node<int>(); //根节点的又子树
root->right->left = new Node<int>();
root->right->left->left = new Node<int>();
root->right->right = new Node<int>();

  遍历

  递归方式

template<typename T>
void traversalRecursion(const struct Node<T>* const p)
{
if (p != nullptr)
{
cout << p->val; traversalRecursion(p->left);
traversalRecursion(p->right);
}
else
cout << "#";
}

  非递归方式——用栈消除递归

template<typename T>
void traversalStack(struct Node<T> *const root)
{
stack<struct Node<T>*> s; s.push(root); while (s.size())
{
struct Node<T> *const p = s.top(); s.pop(); if (p == nullptr)
{
cout << "#";
continue;
} cout << p->val; s.push(p->right);
s.push(p->left);
}
}

  表达式树

  后缀表达式:  a b + c d e + * *

  从“后缀表达式”开始构造一颗表达式树,仅类定义

template<typename T>
class ExpressionTree
{
public:
struct Node<T>* initFormPostfix(const string &postfix)
{
istringstream iss(postfix);
T c; while (iss >> c)
{
struct Node<T> *const p = new struct Node<T>(c); switch (characterType(c))
{
case :
sk.push(p);
break; case :
p->right = sk.top(); sk.pop();
p->left = sk.top(); sk.pop(); sk.push(p);
break;
}
} return sk.top();
} private:
int characterType(const T &c) const
{
if (c == "+" || c == "-" || c == "*" || c == "/")
return ; return ;
} stack<struct Node<T>*> sk;
};

  完整代码

#include <iostream>
#include <string>
#include <sstream>
#include <stack>
#include <memory> using namespace std; template<typename T>
struct Node
{
Node(T v) : val(v), left(nullptr), right(nullptr) {};
T val;
struct Node *left;
struct Node *right;
}; template<typename T>
class ExpressionTree
{
public:
struct Node<T>* initFormPostfix(const string &postfix)
{
istringstream iss(postfix);
T c; while (iss >> c)
{
struct Node<T> *const p = new struct Node<T>(c); switch (characterType(c))
{
case :
sk.push(p);
break; case :
p->right = sk.top(); sk.pop();
p->left = sk.top(); sk.pop(); sk.push(p);
break;
}
} return sk.top();
} private:
int characterType(const T &c) const
{
if (c == "+" || c == "-" || c == "*" || c == "/")
return ; return ;
} stack<struct Node<T>*> sk;
}; template<typename T>
void traversalRecursion(const struct Node<T>* const p)
{
if (p != nullptr)
{
cout << p->val; traversalRecursion(p->left);
traversalRecursion(p->right);
}
else
cout << "#";
} int main()
{
string postfix = "a b + c d e + * *"; ExpressionTree<string> et; const struct Node<string> *root = et.initFormPostfix(postfix); traversalRecursion(root); return ;
}

  二叉查找树

  构建

  构建如图所示的二叉查找树

  构建 + 遍历 代码如下

#include <iostream>
#include <initializer_list>
#include <stack> using namespace std; template<typename T>
struct Node
{
Node(T v) : val(v), left(nullptr), right(nullptr) {}
T val;
struct Node* left;
struct Node* right;
}; template<typename T>
class BinarySearchTree
{
public:
BinarySearchTree()
{
root = new struct Node<T>();
} BinarySearchTree(const initializer_list<T> il) : BinarySearchTree()
{
initializer_list<T>::iterator it = il.begin(); root->val = *it++; while (it != il.end())
insert(*it++);
} void insert(const T &val)
{
struct Node<T> **p = &root; while (*p != nullptr)
{
if (val == (*p)->val)
return; if (val < (*p)->val)
{
p = &((*p)->left);
continue;
} if (val > (*p)->val)
{
p = &((*p)->right);
continue;
}
} *p = new struct Node<T>(val);
} void traversalStack()
{
stack<struct Node<T>*> s; s.push(root); while (s.size())
{
struct Node<T> *const p = s.top(); s.pop(); if (p == nullptr)
{
cout << "#";
continue;
} cout << p->val; s.push(p->right);
s.push(p->left);
}
} private:
struct Node<T> *root;
}; int main(void)
{
BinarySearchTree<int> bst({ , , , , , , , , }); bst.traversalStack(); return ;
}

  查找 代码如下

struct Node<T>* find(const T &val) const
{
struct Node<T> *p = root; while (p != nullptr)
{
if (p->val == val)
return p; if (val < p->val)
p = p->left; if (val > p->val)
p = p->right;
} return nullptr;
}

   树的遍历

  后序遍历

  利用后序遍历求树的深度

unsigned getBinaryTreeHeigt(const struct Node *const p)
{
if (p == nullptr)
return -;
else
return + max(getBinaryTreeHeigt(p->left), getBinaryTreeHeigt(p->right));
}

  层序遍历

  代码一,非递归实现

void levelOrderTraversal(struct Node *root)
{
queue<struct Node*> q; q.push(root); while (q.size())
{
struct Node *p = q.front(); q.pop(); if (p == nullptr)
continue; q.push(p->left);
q.push(p->right); cout << p->val << " ";
}
}

  代码二,递归实现

void levelVisit(queue<struct Node*> &que) {
if (que.empty()) return; struct Node *p = que.front(); que.pop(); if (p == nullptr) return; cout << p->val << " "; que.push(p->left);
que.push(p->right); levelVisit(que);
}

  利用队列可以完成二叉树的层序遍历(广度优先遍历);利用栈可以完成二叉树的深度优先遍历。

  

树(Heap)的更多相关文章

  1. BZOJ.3489.A simple rmq problem(主席树 Heap)

    题目链接 当时没用markdown写,可能看起来比较难受...可以复制到别的地方看比如DevC++. \(Description\) 给定一个长为n的序列,多次询问[l,r]中最大的只出现一次的数.强 ...

  2. 清北学堂 2020 国庆J2考前综合强化 Day2

    目录 1. 题目 T1 一 题目描述 Sol T2 二 题目描述 Sol T3 三 题目描述 Sol T4 四 题目描述 Sol 2. 算法 -- 数据结构 1. 题目 T1 一 题目描述 问题描述 ...

  3. 左偏树(Leftist Heap/Tree)简介及代码

    左偏树是一种常用的优先队列(堆)结构.与二叉堆相比,左偏树可以高效的实现两个堆的合并操作. 左偏树实现方便,编程复杂度低,而且有着不俗的效率表现. 它的一个常见应用就是与并查集结合使用.利用并查集确定 ...

  4. Codeforces Round #300 F - A Heap of Heaps (树状数组 OR 差分)

    F. A Heap of Heaps time limit per test 3 seconds memory limit per test 512 megabytes input standard ...

  5. zoj-3963 Heap Partition(贪心+二分+树状数组)

    题目链接: Heap Partition Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge A sequence ...

  6. 笛卡尔树 POJ ——1785 Binary Search Heap Construction

    相应POJ 题目:点击打开链接 Binary Search Heap Construction Time Limit: 2000MS   Memory Limit: 30000K Total Subm ...

  7. POJ-1785-Binary Search Heap Construction(笛卡尔树)

    Description Read the statement of problem G for the definitions concerning trees. In the following w ...

  8. L - A Heap of Heaps CodeForces - 538F 主席树

    L - A Heap of Heaps CodeForces - 538F 这个是一个还比较裸的静态主席树. 这个题目的意思是把这个数组变成k叉树,然后问构成的树的子树小于等于它的父节点的对数有多少. ...

  9. POJ 1785 Binary Search Heap Construction(裸笛卡尔树的构造)

    笛卡尔树: 每个节点有2个关键字key.value.从key的角度看,这是一颗二叉搜索树,每个节点的左子树的key都比它小,右子树都比它大:从value的角度看,这是一个堆. 题意:以字符串为关键字k ...

随机推荐

  1. 背包----Proud merchants

    一件物品p,q,v 分别表示物品的价格,钱少于q时就不能买,和物品的价值 n表示物品数量,m表示初始有的钱 问最多能买多少东西 01背包 注意点是,因为有一个q作为限制条件,所以n件物品不是随意选的了 ...

  2. spring boot+mybatis 系列

    https://blog.csdn.net/linxingliang/article/details/52324937 https://www.cnblogs.com/a8457013/p/90749 ...

  3. POJ_2533_Longest Ordered Subsequence

    Longest Ordered Subsequence Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 55490   Acc ...

  4. 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。

    1. [推荐]高并发服务器建议调小 TCP 协议的 time_wait 超时时间. 说明:操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服 务器端会因为处于 ...

  5. ddt ddl dml

    data-definition language 数据定义语言 data-manipulation language 数据操纵语言 data type definition 文档类型定义

  6. Python-OpenCV —— 基本操作详解

    OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows.MacOS操作系统上.它轻量级而且高效——由一系列 C 函数和少量C++类构成,同时提供了Pyt ...

  7. struts2 错误:Dispatcher initialization failed java.lang.RuntimeException

    严重: Dispatcher initialization failed java.lang.RuntimeException: java.lang.reflect.InvocationTargetE ...

  8. vue.set的用法

    Vue.set(this.food,'count',1) //就是给this.food里面添加一个count的属性,并且赋值为1

  9. SpringBoot打成的jar包发布,shell关闭之后一直在服务器运行

    1:可以编写shell脚本, 切换到执行的jar包目录,然后使用nohup  让改命令在服务器一直运行 #!/bin/bash cd /srv/ftp/public nohup java -jar l ...

  10. (转载)【cocos2dx 3.x Lua] 注册事件函数详解

    出处: http://www.2cto.com/kf/201409/338235.html coocs2dx 版本 3.1.1 registerScriptTouchHandler 注册触屏事件 re ...