对于大量的输入数据,链表的线性访问时间太慢,不宜使用——《数据结构与算法分析——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. CVPR2018资源汇总

    CVPR 2018大会将于2018年6月18~22日于美国犹他州的盐湖城(Salt Lake City)举办. CVPR2018论文集下载:http://openaccess.thecvf.com/m ...

  2. 【紫书】 Unix ls UVA - 400 模拟

    题意:中文版https://vjudge.net/problem/UVA-400#author=Zsc1615925460 题解:首先读取字符,维护一个最长字符串长度M,再排序. 对于输出,写一个pr ...

  3. CCCC L2-002. 链表去重

    https://www.patest.cn/contests/gplt/L2-002 模拟一个链表的去重操作 题解:别模拟了,直接用内置的list和map.关于输出的地址,直接用pair存地址和值,输 ...

  4. linux:查看以及管理进程

    学习笔记内容概要 进程查看的命令:top,ps,pstree 进程管理的命令:kill,nice,renice 查看进程: 一.top工具 top 工具是我们常用的一个查看工具,能实时的查看我们系统的 ...

  5. JavaScript中的对象描述符(属性特性)

    我们先创建一个对象: var person = { name: "Nicholas", _job: "Software Engineer", sayName: ...

  6. scrollView + tableview 上下滑动失效

    scrollView + tableview 上下滑动失效 控制器添加的  要加到子控制器,不然被销毁了 [self addChildViewController:chatVC];

  7. Find The Multiple--POJ1426

    Description Given a positive integer n, write a program to find out a nonzero multiple m of n whose ...

  8. 【Python】easygui小甲鱼

    翻译改编自官方文档:http://easygui.sourceforge.net/tutorial/index.html 翻译改编者:小甲鱼,本文欢迎转载,转载请保证原文的完整性! 演示使用 Pyth ...

  9. 007-spring cloud gateway-GatewayAutoConfiguration核心配置-RouteDefinition初始化加载

    一.RouteDefinitionLocator 在Spring-Cloud-Gateway的GatewayAutoConfiguration初始化加载中会加载RouteDefinitionLocat ...

  10. 后缀名htm与html的区别

    前者是超文本标记(Hypertext Markup) 后者是超文本标记语言(Hypertext Markup Language) 可以说 htm = html 同时,这两种都是静态网页文件的扩展名,扩 ...