您的位置:首页 > 职场人生

二叉树的完整操作

2017-05-07 13:45 411 查看
#include <iostream>
using namespace std;
#include <queue>
#include <stack>
#include <list>

template<class T>
struct BinaryTreeNode
{
BinaryTreeNode(const T& data)
: _data(data)
, _pLeft(NULL)
, _pRight(NULL)
{}

T _data;
BinaryTreeNode<T>* _pLeft;    // 左孩子
BinaryTreeNode<T>* _pRight;   // 右孩子
};

template<class T>
class BinaryTree
{
typedef BinaryTreeNode<T> Node;
public:
BinaryTree()
: _pRoot(NULL)
{}

//构造二叉树
BinaryTree(const T array[], size_t size, const T& invalid)
{
// 创建树
size_t index = 0;
_CreateTree(_pRoot, array, size, index, invalid);
}

//拷贝二叉树
BinaryTree(const BinaryTree<T>& t)
{
_pRoot = _CopyBinaryTree(t._pRoot);
}

//二叉树的赋值函数
BinaryTree<T>& operator=(const BinaryTree<T>& t)
{
if(this != NULL)
{
_DestroyTree(_pRoot);
_pRoot = _CopyBinaryTree(t._pRoot);

return *this;
}

}

// 递归前序遍历:访问根结点-->左子树-->右子树
void PreOrder()
{
cout<<"递归前序遍历:";
_PreOrder(_pRoot);
cout<<endl<<endl;
}

// 非递归前序遍历:访问根结点-->左子树-->右子树
void PreOrder_Nor()
{
cout<<"非递归前序遍历:";
if(_pRoot == NULL)//空树
return;

stack<Node*> s;
s.push(_pRoot); //根节点入栈

while(!s.empty())
{
Node* pCur = s.top(); //取当前节点
cout<<pCur->_data<<" "; //访问当前节点
s.pop(); //出栈

if(pCur->_pRight)
s.push(pCur->_pRight); //右子树先入栈

if(pCur->_pLeft)
s.push(pCur->_pLeft); //左子树再入栈
}

cout<<endl<<endl;
}

// 递归中序遍历:访问左子树-->根结点-->右子树
void InOrder()
{
cout<<"中序遍历:";
_InOrder(_pRoot);
cout<<endl<<endl;
}

// 非递归中序遍历:访问左子树-->根结点-->右子树
void InOrder_Nor()
{
cout<<"非递归中序遍历:";
if(_pRoot == NULL)
return;  //空树

Node* pCur = _pRoot;
stack<Node*> s;

while(!s.empty() || pCur)
{
//找最左边节点,并保存该路径上的所有节点
while(pCur)
{
s.push(pCur);
pCur = pCur->_pLeft;
}

pCur = s.top(); //取栈顶
cout<<pCur->_data<<" "; //访问
s.pop(); //出栈

pCur = pCur->_pRight;
}

cout<<endl<<endl;
}

// 后序遍历:访问左子树-->右子树-->根节点
void PostOrder()
{
cout<<"后序遍历:";
_PostOrder(_pRoot);
cout<<endl<<endl;
}

// 后续遍历的非递归版本:访问左子树-->右子树-->根节点
void PostOrder_Nor()
{
cout<<"非递归中序遍历:";
if(_pRoot == NULL)
return;

Node* pCur = _pRoot;
Node* prev = NULL;
stack<Node*> s;

while(!s.empty() || pCur)
{
//找最左边节点并保存路径上所有节点
while(pCur)
{
s.push(pCur);
pCur = pCur->_pLeft;
}

pCur = s.top(); //取栈顶
if(pCur->_pRight == NULL || prev == pCur->_pRight)
{
cout<<pCur->_data<<" "; //访问
prev = pCur; //标记
s.pop();
pCur = NULL;
}

else
{
pCur = pCur->_pRight;
}
}

cout<<endl<<endl;
}

// 层序遍历
void LevelOrder()
{
cout<<"层序遍历:";
_LevelOrder(_pRoot);
cout<<endl<<endl;
}

~BinaryTree()
{
_DestroyTree(_pRoot);
_pRoot = NULL;
}

//找到节点的双亲节点
Node* GetParent(Node* x)
{
return _GetParent(_pRoot,x);
}

//找到结点的左孩子
Node* GetLeftChild(Node* pCur)
{
return pCur->_pLeft;
}

//找到结点的右孩子
Node* GetRightChild(Node* pCur)
{
return pCur->_pRight;
}

//在二叉树中查找某个节点
Node* Find(const T& value)
{
return _Find(_pRoot, value);
}

//二叉树的高度
size_t Height()
{
return _Height(_pRoot);
}

//叶子结点的个数
size_t GetLeefNode()
{
return _GetLeefNode(_pRoot);
}

//第K层有几个节点
size_t GetKLevelNode(size_t k)
{
return _GetKLevelNode(_pRoot, k);
}

// 求二叉树的镜像:非递归
void GetBinaryMirror_Nor()
{
queue<Node *> q;
Node *pointer = _pRoot;//当前处理的节点为根节点
while (pointer)
{
swap(pointer->_pLeft, pointer->_pRight);//交换当前处理节点的孩子
if (pointer->_pLeft)//左孩子不为空
q.push(pointer->_pLeft);

if (pointer->_pRight)//右孩子不为空
q.push(pointer->_pRight);

if (!q.empty())
{
pointer = q.front();
q.pop();
}
else
{
break;
}
}
}

// 求二叉树的镜像:递归版本
void GetBinaryMirror()
{
return _GetBinaryMirror(_pRoot);
}

// 利用层序遍历来处理--> 关键:找第一个度不为2的结点-->后续结点
// 如果有孩子则不是完全二叉树
// 否则:是
bool IsCompleteBinaryTree()
{
if(_pRoot == NULL)
return true;
Node* pCur = NULL;
queue<Node*> q;
q.push(_pRoot);

int flag = false;

while(!q.empty())
{
pCur = q.front();
q.pop();

if(flag == true)
{
if(pCur->_pLeft != NULL || pCur->_pRight != NULL)
return false;
return true;
}
else
{
if(pCur->_pLeft != NULL && pCur->_pRight != NULL)
{
q.push(pCur->_pLeft);
q.push(pCur->_pRight);
}
else if(pCur->_pRight!= NULL)
{
return false;
}
else if(pCur->_pLeft != NULL)
{
q.push(pCur->_pLeft);
flag = true;
}
else
{
flag = true;
}
}
}
return false;
}

// 求二叉树中两个节点的最近公共祖先节点
Node* GetLastCommonParent(Node* Node1, Node* Node2)
{
return _GetLastCommonParent(_pRoot, Node1, Node2);
}

// 由前序遍历序列和中序遍历序列重建二叉树
Node* RebuildBinaryTree(char* PreOrder, char* InOrder, int length)
{
//int len1 = sizeof(PreOrder/PreOrder[0]);
//int len2 = sizeof(InOrder/InOrder[0]);

//if(len1 != len2)
//return NULL;

if(PreOrder == NULL || InOrder == NULL || length < 0)
return NULL;

// 前序遍历的第一个数据就是根节点数据
Node* _pRoot = new BinaryTreeNode<char>(PreOrder[0]);

// 查找根节点在中序遍历中的位置,中序遍历中,根节点左边为左子树,右边为右子树
int rootPositionInOrder = -1;
for(int i = 0; i < length; i++)
{
if(InOrder[i] == _pRoot->_data)
{
rootPositionInOrder = i;
break;
}
}

// 重建左子树
int nodeNumLeft = rootPositionInOrder;
char* pPreOrderLeft = PreOrder + 1;
char* pInOrderLeft = InOrder + nodeNumLeft;
_pRoot->_pLeft = RebuildBinaryTree(pPreOrderLeft, pInOrderLeft, nodeNumLeft);

// 重建右子树
int nodeNumRight = length - nodeNumLeft - 1;
char* pPreOrderRight = PreOrder + 1 + nodeNumLeft;
char* pInOrderRight = InOrder + nodeNumLeft + 1;
_pRoot->_pRight = RebuildBinaryTree(pPreOrderRight, pInOrderRight, nodeNumRight);
return _pRoot;
}

private:
void _CreateTree(Node*& pRoot, const T array[],
size_t size, size_t& index, const T& invalid)
{
if(index < size && (array[index] != invalid))//两个顺序不可调换,否则会导致越界访问
{
//创建根节点
pRoot = new Node(array[index]);

//创建根结点左子树
_CreateTree(pRoot->_pLeft, array, size, ++index, invalid);

//创建根结点左子树
_CreateTree(pRoot->_pRight, array, size, ++index, invalid);
}
}

Node* _CopyBinaryTree(Node* pRoot)
{
if(pRoot)
{
Node* pNewNode = new Node(pRoot->_data);
pNewNode->_pLeft = _CopyBinaryTree(pRoot->_pLeft);
pNewNode->_pRight = _CopyBinaryTree(pRoot->_pRight);
return pNewNode;
}
return NULL;
}

void _DestroyTree(Node* &pRoot)
{
if(pRoot)
{
_DestroyTree(pRoot->_pLeft);
_DestroyTree(pRoot->_pRight);
delete pRoot;
pRoot = NULL;
}
}

void _PreOrder(Node* pRoot)
{
if(pRoot)
{
cout<<pRoot->_data<<" ";
_PreOrder(pRoot->_pLeft);
_PreOrder(pRoot->_pRight);
}
}

void _InOrder(Node* pRoot)
{
if(pRoot)
{
_InOrder(pRoot->_pLeft);
cout<<pRoot->_data<<" ";
_InOrder(pRoot->_pRight);
}

}

void _PostOrder(Node* pRoot)
{
if(pRoot)
{
_PostOrder(pRoot->_pLeft);
_PostOrder(pRoot->_pRight);
cout<<pRoot->_data<<" ";
}
}

void _LevelOrder(Node* pRoot)
{
if(pRoot == NULL)
return;
queue<Node*> q;
q.push(pRoot);
Node* pCur = NULL;

while(!q.empty())
{
pCur = q.front();
cout<<pCur->_data<<" ";
if(pCur->_pLeft)
q.push(pCur->_pLeft);
if(pCur->_pRight)
q.push(pCur->_pRight);
q.pop();
}
}

Node* _GetParent(Node* pRoot, Node* x)
{
if(pRoot == NULL || x ==  NULL || x == pRoot)
return NULL;

if(pRoot->_pLeft == x || pRoot->_pRight == x)
return pRoot;

Node* parent = NULL;
if(parent = _GetParent(pRoot->_pLeft, x))
return parent;

if(parent = _GetParent(pRoot->_pRight, x))
return parent;

return NULL;
}

Node* _Find(Node* pRoot, const T& value)
{
if(pRoot == NULL)  //空树
return NULL;

if(pRoot->_data == value)
return pRoot;

Node* pCur = NULL;//如果不用返回值接收需要再调用一次函数
if(pCur = _Find(pRoot->_pLeft, value))
return pCur;

if(pCur = _Find(pRoot->_pRight, value))
return pCur;
}

size_t _Height(Node* pRoot)
{
if(pRoot == NULL)  //空树
return 0;

if(pRoot->_pLeft == NULL || pRoot->_pRight == NULL)
return 1;   //只有一个根节点的树

size_t lefthHight = _Height(pRoot->_pLeft);
size_t rightHeight = _Height(pRoot->_pRight);

return (lefthHight>rightHeight) ? (lefthHight+1) : (rightHeight+1);
}

size_t _GetLeefNode(Node* pRoot)
{
if(pRoot == NULL) //空树
return 0;

if(pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
return 1;  //只有一个根节点的树

return _GetLeefNode(pRoot->_pLeft) + _GetLeefNode(pRoot->_pRight);
}

size_t _GetKLevelNode(Node* pRoot, size_t k)
{
if(pRoot == NULL || k<1 || k>_Height(pRoot))
return 0;

if(k == 1)
return 1;

size_t left = _GetKLevelNode(pRoot->_pLeft, k-1);
size_t right = _GetKLevelNode(pRoot->_pRight, k-1);

return left + right;
}

void _GetBinaryMirror(Node* pRoot)
{
if(pRoot == NULL)
return ;

if(pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
return ;

swap(pRoot->_pLeft, pRoot->_pRight);

if(pRoot->_pLeft)
_GetBinaryMirror(pRoot->_pLeft);

if(pRoot->_pRight)
_GetBinaryMirror(pRoot->_pRight);
}

bool GetNodePath(Node* pRoot, Node* pNode, list<Node*>& path)
{
if(pRoot == pNode)
{
path.push_back(pRoot);
return true;
}

if(pRoot == NULL)
return false;

path.push_back(pRoot);
bool found = false;

found = GetNodePath(pRoot->_pLeft, pNode, path);  //在左子树中寻找

if(!found)  //在左子树中没有找到,在右子树中寻找
found = GetNodePath(pRoot->_pRight, pNode, path);

if(!found)   //没有找到该节点
path.pop_back();
return found;
}

Node* _GetLastCommonParent(Node* pRoot, Node* Node1, Node* Node2)
{
if(pRoot == NULL || Node1 == NULL || Node2 == NULL)
return NULL;

list<Node*> l1;
bool Result1 = GetNodePath(pRoot, Node1, l1);

list<Node*> l2;
bool Result2 = GetNodePath(pRoot, Node2, l2);

if(!Result1 || !Result2)
return NULL;

Node * pLast = NULL;
list<Node*>::const_iterator iter1 = l1.begin();
list<Node*>::const_iterator iter2 = l2.begin();

while(iter1 != l1.end() && iter2 != l2.end())
{
if(*iter1 == *iter2)
pLast = *iter1;
else
break;
iter1++;
iter2++;
}
return pLast;
}

private:
BinaryTreeNode<T>* _pRoot;
};

void FunTest()
{
char array[] = "124##5##36##7##";
BinaryTree<char> tree(array, strlen(array), '#');
BinaryTree<char> t(tree);
BinaryTree<char> t1;
t1 = t;

BinaryTreeNode<char>* pCur = NULL;
pCur = t.GetParent(t.Find('1')); //找到节点的双亲节点
if(pCur)
cout<<"结点1的双亲结点为:"<<pCur->_data<<endl;

pCur = t.GetParent(t.Find('2'));
if(pCur)
cout<<"结点2的双亲结点为:"<<pCur->_data<<endl;

pCur = t.GetParent(t.Find('5'));
if(pCur)
cout<<"结点5的双亲结点为:"<<pCur->_data<<endl;

pCur = t.GetLeftChild(t.Find('1')); //找到结点的左孩子
if(pCur)
cout<<"结点1的左孩子为:"<<pCur->_data<<endl;

pCur = t.GetLeftChild(t.Find('3'));
if(pCur)
cout<<"结点2的左孩子为:"<<pCur->_data<<endl;

pCur = t.GetLeftChild(t.Find('6'));
if(pCur)
cout<<"结点6的左孩子为:"<<pCur->_data<<endl;

pCur = t.GetRightChild(t.Find('1')); //找到结点的右孩子
if(pCur)
cout<<"结点1的右孩子为:"<<pCur->_data<<endl;

pCur = t.GetRightChild(t.Find('2'));
if(pCur)
cout<<"结点2的右孩子为:"<<pCur->_data<<endl;

pCur = t.GetRightChild(t.Find('5'));
if(pCur)
cout<<"结点5的右孩子为:"<<pCur->_data<<endl;

cout<<"二叉树的高度:"<<t.Height()<<endl;
cout<<"二叉树的叶子节点:"<<t.GetLeefNode()<<endl;
cout<<"二叉树第三层的节点数:"<<t.GetKLevelNode(3)<<endl;
cout<<"二叉树第二层的节点数:"<<t.GetKLevelNode(2)<<endl;
cout<<"二叉树第一层的节点数:"<<t.GetKLevelNode(1)<<endl;
cout<<"二叉树第四层的节点数:"<<t.GetKLevelNode(4)<<endl;

tree.PreOrder();
t.PreOrder_Nor();

tree.InOrder();
t.InOrder_Nor();

tree.PostOrder();
tree.PostOrder_Nor();

tree.LevelOrder();

tree.GetBinaryMirror_Nor();
tree.GetBinaryMirror();

cout<<"二叉树是不是完全二叉树:"<<t.IsCompleteBinaryTree()<<endl;
pCur = tree.GetLastCommonParent(tree.Find('2'), tree.Find('6'));
if(pCur)
cout<<"结点2和5的公共祖先是"<<pCur->_data<<endl;

char str1[] = {'1', '2', '4', '5', '3', '6', '7'};
char str2[] = {'4', '2', '5', '1', '6', '3', '7'};
tree.RebuildBinaryTree(str1, str2, 7);
}

int main()
{
FunTest();
system("pause");

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息