对于大量的输入数据,链表的线性访问时间太慢,不宜使用——《数据结构与算法分析——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. codeforces 883H - Palindromic Cut - [字符串处理]

    题目链接:http://codeforces.com/problemset/problem/883/H Time limit: 3000 ms Memory limit: 262144 kB Koly ...

  2. UOJ 145 - 神奇的幻方 - [简单数学题]

    题目链接:http://uoj.ac/problem/145 题目描述 幻方是一种很神奇的 N∗N 矩阵:它由数字 1,2,3,⋯⋯,N×N 构成,且每行.每列及两条对角线上的数字之和都相同. 当 N ...

  3. Python爬虫框架Scrapy实例(四)下载中间件设置

    还是豆瓣top250爬虫的例子,添加下载中间件,主要是设置动态Uesr-Agent和代理IP Scrapy代理IP.Uesr-Agent的切换都是通过DOWNLOADER_MIDDLEWARES进行控 ...

  4. 2018/03/11 每日一个Linux命令 之 top

    每日一个Linux命令 之 top   今天在公司测试服务器上跑了一个我写的功能[本地测试过的],但是不知道怎么跑了个无限死循环出来,一个文件的体积在不停的变大,如果不管的话这能行? 上去一看,PHP ...

  5. 【Mysql优化三章】第一章

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/Bv5f4b8Peex/article/details/78130845 如今网上的好多mysql优化 ...

  6. Java-idea-生成for循环

    itar 生成array for代码块 for (int i = 0; i < array.length; i++) { = array[i]; } itco 生成Collection迭代 fo ...

  7. SQL 1

    SQL 教程 SQL 是用于访问和处理数据库的标准的计算机语言. 在本教程中,您将学到如何使用 SQL 访问和处理数据系统中的数据,这类数据库包括:MySQL.SQL Server.Access.Or ...

  8. Ceph 分布式存储

    前言 Ceph是一个分布式存储系统,诞生于2004年,最早致力于开发下一代高性能分布式文件系统的项目.随着云计算的发展,ceph乘上了OpenStack的春风,进而成为了开源社区受关注较高的项目之一. ...

  9. 查看Django和flask版本

    查看Django版本 检查是否安装成功,可以在dos下查看Django版本. 1.输入python 2.输入import django 3.输入django.get_version() 1 2 3 4 ...

  10. hdu3339In Action(最短路+01背包)

    http://acm.sdut.edu.cn:8080/vjudge/contest/view.action?cid=259#problem/H Description Since 1945, whe ...