本文整理自:https://www.cnblogs.com/33debug/p/7248822.html,特此感谢!

 

一、相关概念

树是n( n>=0)个有限个数据的元素集合,它的数据的存储结构形状像一颗倒过来的树。根在上,叶在下:如图所示

(转) 二叉树常见面试题1

1.一个独立的节点也可看作一棵树,它既为根节点,又为叶子节点;

2.一个节点也没有称作空树;

(转) 二叉树常见面试题1

3.这是一颗典型的树,根节点为A;

(转) 二叉树常见面试题1

4.一个节点只有唯一父节点。

节点: 结点包含数据和指向其它节点的指针。
根节点: 树第一个结点称为根节点。
结点的度: 结点拥有的子节点个数。
叶节点: 没有子节点的节点(度为0)。
父子节点: 一个节点father指向另一个节点child, 则child为孩子节点, father为父亲节点 。
兄弟节点: 具有相同父节点的节点互为兄弟节点。
节点的祖先: 从根节点开始到该节点所经的所有节点都可以称为该节点的祖先。
子孙: 以某节点为根的子树中任一节点都称为该节点的子孙。
树的高度: 树中距离根节点最远节点的路径长度。

如图示:

(转) 二叉树常见面试题1

5.树的存储结构

struct TreeNode
{
      DataType data; //节点值
      TreeNode*  _firistchild;   //第一个孩子
      TreeMode* _nextchild;   //第二个孩子
       ...     
};

  有时候根据需要还会加入父节点,结构如下:

struct TreeNode
 {
         DataType data; //节点值
         TreeNode* _parent;
         TreeNode*  _firistchild;   //第一个孩子
         TreeMode* _nextchild;   //第二个孩子
          ...     
 };

二、二叉树

1.二叉树:二叉树是一棵特殊的树, 二叉树每个节点最多有两个孩子结点, 分别称为左孩子和右孩子。如图:

 (转) 二叉树常见面试题1

2.存储结构

 (转) 二叉树常见面试题1

template <class T>
  struct TreeNode  //定义二叉树结点
  {
      TreeNode<T>* _left;   //指向左子树的指针
      TreeNode<T>* _right;  //指向右子树的指针
      T _data;  //节点数据
      TreeNode(const T& n)
          :_left(NULL)
         ,_right(NULL)
         ,_data(n)
     {}
 };

有时候根据需要还会加入父节点,结构如下:

(转) 二叉树常见面试题1

template <class T>
struct TreeNode  //定义二叉树结点
{
    TreeNode<T>* _parent;  //指向父节点的指针
    TreeNode<T>* _left;   //指向左子树的指针
    TreeNode<T>* _right;  //指向右子树的指针
    T _data;  //节点数据
    TreeNode(const T& n)
        :_left(NULL)
        ,_right(NULL)
        ,_data(n)
    {}
};

3.特殊的二叉树

满二叉树:高度为N的满二叉树有2^N - 1个节点的二叉树。
完全二叉树: 若设二叉树的深度为h, 除第 h 层外, 其它各层 (1~ h-1) 的结点数都达到最大个数, 第 h 层所有的结点都连续集中在最左
边, 这就是完全二叉树

 (转) 二叉树常见面试题1(转) 二叉树常见面试题1

对于上面这颗完全二叉树:

前序遍历(先根遍历):     根左右   【1 2 3 4 5 6】
中序遍历:                      左根右   【3 2 4 1 6 5】
后序遍历(后根遍历):     左右根   【3 4 2 6 5 1】
层序遍 历:  一层层节点依次遍历【1 2 5 3 4 6】

 

三、对二叉树的相关操作

#pragma once
#include <iostream>
#include <queue>
using namespace std;

template <class T>
struct BinaryTreeNode  //定义二叉树结点
{
    BinaryTreeNode<T>* _left;   //指向左子树的指针
    BinaryTreeNode<T>* _right;  //指向右子树的指针
    T _data;  //节点数据
    BinaryTreeNode(const T& n)
        :_left(NULL)
        ,_right(NULL)
        ,_data(n)
    {}
};

template <class T>
class BinaryTree
{
    typedef BinaryTreeNode<T> Node; 
public:
    BinaryTree()  //空树
        :_root(NULL)
    {}
    BinaryTree(const BinaryTree<T>& tree)  //拷贝构造
    {
        _root = _Copy(tree._root);
    }
    ~BinaryTree()  //析构二叉树
    {
        _Destroy(_root);
        _root = NULL;
    }
    BinaryTree<T>& operator=(const BinaryTree<T>& tree) //赋值运算符重载
    {
        if (this != &tree) {
            _Destroy(_root);
            _root = _Copy(tree._root);
        }
        return *this
    }
    
    /*BinaryTree<T>& operator=(const BinaryTree<T>& tree)
    {
        swap(_root, tree._root);
        return *this;
    }*/
    BinaryTree(T* a, size_t n, const T& invalid) {  //invalid无效节点(#)//创建节点个数为N的二叉树
        size_t index = 0;
        _root = _CreatTree(a, n, invalid, index); 
    }
    void PrevOrder(){  //前序遍历二叉树递归法
        _PrevOrder(_root);
        cout << endl;
    }
    void PrevOrderNonR()  //前序遍历二叉树非递归法
    {
        _PrevOrderNonR(_root);
        cout << endl;
    }
    void InOrder()  //中序遍历二叉树递归法
    {
        _InOrder(_root);
        cout << endl;
    }
    void InOrderNonR()  //中序遍历二叉树非递归法
    {
        _InOrderNonR(_root);
        cout << endl;
    }
    void PostOrder()  //后序遍历二叉树递归法
    {
        _PostOrder(_root);
        cout << endl;
    }
    void PostOrderNonR()  //后序遍历二叉树非递归法
    {
        _PostOrderNonR();
        cout << endl;
    }
    void LevelOrder()   //层序遍历二叉树递归法
    {
        _LevelOrder(_root);
        cout << endl;
    }
    void LevelOrderNonR()//.queue//层序遍历二叉树非递归法
    {
        _LevelOrderNonR(_root);
        cout << endl;
    }
    size_t Size(){  //二叉树总节点个数
        return _Size(_root);
    }
    size_t CountLeafNode()   //叶子节点
    {
        return _CountLeafNode(_root);
    }
    size_t Depth()  //高度
    {
        return _Depth(_root);
    }
    size_t GetKLevelSize(size_t k)  //第K层节点个数
    {
        return _GetKLevelSize(_root, k);
    }
    Node* Find(const T& x)  //查找节点
    {
        return _Find(_root, x);
    }
private:
    Node * _root;  //根节点
    Node* _CreatTree(T* a, size_t n, const T& invalid, size_t &index) {  //创建二叉树树
        Node* root = NULL;
        if (index < n && a[index] != invalid) {
            root = new Node(a[index]);
            root->_left = _CreatTree(a, n, invalid, ++index);//递归创建左子树
            root->_right= _CreatTree(a, n, invalid, ++index);//递归创建右子树
        }
        return root;
    }
    Node* _Copy(Node* root)  //copy二叉树
    {
        if (root == NULL)
            return NULL;
        Node* newroot = new Node(root->_data);
        newroot->_left = _Copy(root->_left);
        newroot->_right = _Copy(root->_right);
    }
    void _Destory(Node* root)  //销毁二叉树树
    {
        if (root == NULL)
            return;
        _Destory(root->_left);
        _Destory(root->_right);
        delete root;
    }
};
View Code

相关文章: