您的位置:首页 > 其它

二叉树的创建及其基础操作

2016-04-28 21:40 253 查看
问题描述:

二叉树这部分的知识可谓是数据结构的重中之重,相关方面的知识点还是蛮多的,虽然有些知识点确实是难度颇高,但是其大部分的知识点还是能简单一些的,,所以在笔试面试中我们多多少少能遇见二叉树的相关题型,可以说二叉树以及其相关拓展的知识点玩儿6了,数据结构至少一半的知识已收入囊中了。

笔试面试中经常会遇到让你写出某个或某些二叉树中的成员函数,例如:节点的遍历顺序(前序,中序,后序,层序),怎样求第K层的节点数,求一个二叉树的高度等,,所以在此先从二叉树的基础构建开始,,逐渐添砖加瓦,一步步完善二叉树的相关操作,希望多多少少能与君共勉。

#include<iostream>
using namespace std;

template<class T>
typedef struct BinaryNode
//定义二叉链表
{
T _data;//值域
BinaryNode<T>* _left;//左孩子节点
BinaryNode<T>* _right;//右孩子节点

BinaryNode(const T&x)
:_left(NULL)
, _right(NULL)
, _data(x)
{}
};

template<class T>
class BinaryTree  //二叉树类
{
typedef BinaryNode<T> Node;//名字太长,用Node代替

public:
BinaryTree()
:_root(NULL)
{}

BinaryTree(const T*a, size_t size, const T&invalid)
:_root(NULL)//a数组利用下标可访问具体节点位置,size为大小,invalid为非法值,例如符号,字母等情况
{
size_t index = 0;
_root = CreateTree(a, size, invalid, index);
}

BinaryTree<T>(const BinaryTree<T>&obj)//拷贝构造函数
: _root(NULL)
{
_root = _Copy(obj._root);
}

BinaryTree<T>& operator=(const BinaryTree<T>&obj)//赋值运算符重载函数
{
if (this != &obj)
{
_Copy(obj._root);
_Destroy(_root);
}
return *this;
}

~BinaryTree()//析构函数
{
if (_root)
{
_Destroy(_root);
}
}

public:
size_t Size()//结点个数:左子树节点+右子树节点+根节点
{
return _Size(_root);
}

size_t Depth()//树的高度(深度):左子树与右子树层数取其大的那一个
{
return _Depth(_root);
}

size_t LeafSize()//叶子节点数:左子树叶子节点+右子树叶子节点
{
return _LeafSize(_root);
}

size_t KLevelSize(int k)//第K层节点
{
return _KLevelSize(_root, k);
}

protected:
void _Destroy(Node* root)//删除节点
{
if (root == NULL)
{
return;
}
if (root->_left == NULL && root->_right == NULL)
{
delete root;
root = NULL;
return;
}
_Destroy(root->_left);
_Destroy(root->_right);
}

Node* _Copy(Node* root)//复制节点
{
if (root == NULL)
{
return NULL;
}
Node* root = new Node(root->_data);

root->_left = _Copy(root->_left);
root->_right = _Copy(root->_right);
return root;
}

size_t _LeafSize(Node* root)
{
if (root == NULL)
{
return 0;
}
if (root->_left == NULL && root->_right == NULL)
{
return 1;
}
return _LeafSize(root->_left) + _LeafSize(root->_right);
}

size_t _Size(Node* root)
{
if (root == NULL)
{
return 0;
}
return _Size(root->_left) + _Size(root->_right) + 1;
}

size_t _Depth(Node* root)
{
if (root == NULL)
{
return 0;
}
int LeftDepth = _Depth(root->_left);
int RightDepth = _Depth(root->_right);
return LeftDepth > RightDepth ? (LeftDepth + 1) : (RightDepth + 1);//利用三目运算符的性质,取其值大的那一个为树的深度
}

size_ t _KLevelSize(Node* root, int k)
{
assert(k > 0);
if (root == NULL)
{
return 0;
}
if (k == 1)
{
return 1;
}
return _KLevelSize(root->_left, k - 1) + _KLevelSize(root->_right, k - 1);
}

Node* _CreateTree(const T*a, size_t size, const T&invalid, size_t &index)//树的创建
{
Node* root = NULL;
if (index < size && a[index] != invalid)
{
root = new Node(a[index]);
root->_left = _CreateTree(a, size, invalid, ++index);
root->_right = _CreateTree(a, size, invalid, ++index);
}
return root;
}

private:
Node* _root;
};


注:关于二叉树的遍历问题,将在下次文章中细细整理,欢迎各大神指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: