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

  构建树并添加节点

  按照如图的树构建

树_第1张图片

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

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

root->right = new Node<int>(5); //根节点的又子树
root->right->left = new Node<int>(6);
root->right->left->left = new Node<int>(8);
root->right->right = new Node<int>(7);
View Code

  遍历

  递归方式

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 << "#";
}
View Code

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

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);
    }
}
View Code

  表达式树

  后缀表达式:  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 0:    
                sk.push(p);
                break;

            case 1:
                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 1;

        return 0;
    }

    stack<struct Node<T>*> sk;
};
View Code

   完整代码

#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 0:    
                sk.push(p);
                break;

            case 1:
                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 1;

        return 0;
    }

    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 0;
}
View Code

  二叉查找树

  构建

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

树_第2张图片

  构建 + 遍历 代码如下

#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>(0);
    }

    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({ 8, 3, 10, 1, 6, 14, 4, 7, 13 });

    bst.traversalStack();

    return 0;
}
View Code

   查找 代码如下

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;
}
View Code

 

 

  

 

你可能感兴趣的:(树)