该篇文章介绍二叉树的一些常用算法。
头文件:BinaryTree.h
#pragma once
#include<iostream>
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
//===二叉树的基本操作运算
BinaryTreeNode* CreateBinaryTreeNode(int value);//创建一个节点
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight);//连接根节点和左右子节点
void PrintTreeNode(BinaryTreeNode* pNode);
void PrintTree(BinaryTreeNode* pRoot);//输出节点
void DestroyTree(BinaryTreeNode* pRoot);//销毁节点
BinaryTreeNode *FindNode(BinaryTreeNode*proot, int x);//查找结点
int BinaryTreeHeight(BinaryTreeNode *proot);//求二叉树的高度
//===二叉树的遍历算法--递归版
void PreOrder(BinaryTreeNode *proot);//前序遍历
void InOrder(BinaryTreeNode *proot);//中序遍历
void PostOrder(BinaryTreeNode *proot);//后序遍历
//===二叉树的遍历算法--迭代版
void PreOrderIter(BinaryTreeNode *proot);//前序遍历
void InOrderIter(BinaryTreeNode *proot);//中序遍历
void PostOrderIter(BinaryTreeNode *proot);//后序遍历
//===二叉树的层次遍历
void LevelOrder(BinaryTreeNode *proot);//层次遍历
//===二叉树的其他操作运算--递归版
int NodeCount(BinaryTreeNode *proot);//二叉树的结点个数
void AllLeavesNode(BinaryTreeNode *proot);//求二叉树的所有叶子结点
void CopyOneToAnthor(BinaryTreeNode *proot, BinaryTreeNode *&other);//由一棵二叉树复制产生另一棵二叉树
void ConvertArrayToBT(int a[], int n, int i, BinaryTreeNode *&proot);//由数组转化为二叉树
int Level(BinaryTreeNode *proot, int x, int h);//x所在的层
bool Ancestor(BinaryTreeNode *proot, int x);//输出节点x的所有祖先结点
BinaryTreeNode *ConstructBTbyPreInOrder(int pre[], int prebegin, int mid[], int midbegin, int n);//由前序和中序构造二叉树
BinaryTreeNode *ConstructBTbyPostInOrder(int post[], int postbegin, int mid[], int midbegin, int n);//由后序和中序构造二叉树
//===二叉树的其他操作运算--迭代版
bool AncestorIter(BinaryTreeNode *proot, int x);//输出节点x的所有祖先结点
源文件:BinaryTree.cpp
#include "BinaryTree.h"
#include<iostream>
#include<stack>
#include<queue>
BinaryTreeNode* CreateBinaryTreeNode(int value)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_nValue = value;
pNode->m_pLeft = NULL;
pNode->m_pRight = NULL;
return pNode;
}
void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
{
if (pParent != NULL)
{
pParent->m_pLeft = pLeft;
pParent->m_pRight = pRight;
}
}
void PrintTreeNode(BinaryTreeNode* pNode)
{
if (pNode != NULL)
{
printf("value of this node is: %d\n", pNode->m_nValue);
if (pNode->m_pLeft != NULL)
printf("value of its left child is: %d.\n", pNode->m_pLeft->m_nValue);
else
printf("left child is null.\n");
if (pNode->m_pRight != NULL)
printf("value of its right child is: %d.\n", pNode->m_pRight->m_nValue);
else
printf("right child is null.\n");
}
else
{
printf("this node is null.\n");
}
printf("\n");
}
void PrintTree(BinaryTreeNode* pRoot)
{
PrintTreeNode(pRoot);
if (pRoot != NULL)
{
if (pRoot->m_pLeft != NULL)
PrintTree(pRoot->m_pLeft);
if (pRoot->m_pRight != NULL)
PrintTree(pRoot->m_pRight);
}
}
void DestroyTree(BinaryTreeNode* pRoot)
{
if (pRoot != NULL)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight;
delete pRoot;
pRoot = NULL;
DestroyTree(pLeft);
DestroyTree(pRight);
}
}
BinaryTreeNode *FindNode(BinaryTreeNode*proot, int x)
{
if (proot == NULL)
return NULL;
else if (proot->m_nValue == x)
return proot;
else
{
BinaryTreeNode *p = FindNode(proot->m_pLeft, x);
if (p == NULL)
return FindNode(proot->m_pRight, x);
else
return p;
}
}
int BinaryTreeHeight(BinaryTreeNode *proot)
{
if (proot == NULL)
return 0;
else
{
int leftheight = BinaryTreeHeight(proot->m_pLeft);
int righrheight = BinaryTreeHeight(proot->m_pRight);
return leftheight > righrheight ? leftheight + 1 : righrheight + 1;
}
}
void PreOrder(BinaryTreeNode *proot)
{
if (proot)
{
std::cout << proot->m_nValue << " ";
PreOrder(proot->m_pLeft);
PreOrder(proot->m_pRight);
}
}
void InOrder(BinaryTreeNode *proot)
{
if (proot)
{
InOrder(proot->m_pLeft);
std::cout << proot->m_nValue << " ";
InOrder(proot->m_pRight);
}
}
void PostOrder(BinaryTreeNode *proot)
{
if (proot)
{
PostOrder(proot->m_pLeft);
PostOrder(proot->m_pRight);
std::cout << proot->m_nValue << " ";
}
}
void PreOrderIter(BinaryTreeNode *proot)
{
if (proot == NULL)
return;
std::stack<BinaryTreeNode*> temp;
temp.push(proot);
while (!temp.empty())
{
BinaryTreeNode *p = temp.top();
temp.pop();
std::cout << p->m_nValue << " ";
if (p->m_pRight)
temp.push(p->m_pRight);
if (p->m_pLeft)
temp.push(p->m_pLeft);
}
std::cout << std::endl;
}
void InOrderIter(BinaryTreeNode *proot)
{
if (proot == NULL)
return;
BinaryTreeNode*p = proot;
std::stack<BinaryTreeNode *> temp;
while (!temp.empty()||p!=NULL)
{
while (p)
{
temp.push(p);
p = p->m_pLeft;
}
if (!temp.empty())
{
p = temp.top();
temp.pop();
std::cout << p->m_nValue << " ";
p = p->m_pRight;
}
}
std::cout << std::endl;
}
void PostOrderIter(BinaryTreeNode *proot)
{
if (proot == NULL)
return;
BinaryTreeNode *p = proot, *q = NULL;
std::stack<BinaryTreeNode*>temp;
bool flag;
do
{
while (p)
{
temp.push(p);
p = p->m_pLeft;
}
q = NULL;
flag = true;
while (!temp.empty() && flag)
{
p = temp.top();
if (p->m_pRight == q)
{
std::cout << p->m_nValue << " ";
q = p;
temp.pop();
}
else
{
p = p->m_pRight;
flag = false;
}
}
} while (!temp.empty());
std::cout << std::endl;
}
void LevelOrder(BinaryTreeNode *proot)
{
if (proot == NULL)
return;
std::queue<BinaryTreeNode*>temp;
temp.push(proot);
while (!temp.empty())
{
BinaryTreeNode *p = temp.front();
std::cout << p->m_nValue << " ";
temp.pop();
if (p->m_pLeft)
temp.push(p->m_pLeft);
if (p->m_pRight)
temp.push(p->m_pRight);
}
std::cout << std::endl;
}
int NodeCount(BinaryTreeNode *proot)
{
if (proot)
{
return 1 + NodeCount(proot->m_pLeft) + NodeCount(proot->m_pRight);
}
else
return 0;
}
void AllLeavesNode(BinaryTreeNode *proot)
{
if (proot)
{
if (proot->m_pLeft == NULL&&proot->m_pRight == NULL)
std::cout << proot->m_nValue << " ";
AllLeavesNode(proot->m_pLeft);
AllLeavesNode(proot->m_pRight);
}
}
void CopyOneToAnthor(BinaryTreeNode *proot, BinaryTreeNode * &other)
{
if (proot)
{
other = CreateBinaryTreeNode(proot->m_nValue);
CopyOneToAnthor(proot->m_pLeft, other->m_pLeft);
CopyOneToAnthor(proot->m_pRight, other->m_pRight);
}
else
{
other = NULL;
}
}
void ConvertArrayToBT(int a[], int n,int i,BinaryTreeNode *&proot)
{
if (i < n)
{
proot = CreateBinaryTreeNode(a[i]);
ConvertArrayToBT(a, n, i * 2 + 1, proot->m_pLeft);
ConvertArrayToBT(a, n, i * 2 + 2, proot->m_pRight);
}
else
proot = NULL;
}
int Level(BinaryTreeNode *proot, int x, int h)
{
if (proot == NULL)
return 0;
if (proot->m_nValue == x)
return h;
else
{
int height = Level(proot->m_pLeft, x, h + 1);
if (height != 0)
return height;
else
return Level(proot->m_pRight, x, h + 1);
}
}
bool Ancestor(BinaryTreeNode *proot, int x)
{
if (proot == NULL)
return false;
if (proot->m_pLeft != NULL&&proot->m_pLeft->m_nValue == x)
{
std::cout << proot->m_nValue << " ";
return true;
}
if (proot->m_pRight != NULL&&proot->m_pRight->m_nValue == x)
{
std::cout << proot->m_nValue << " ";
return true;
}
if (Ancestor(proot->m_pLeft, x) || Ancestor(proot->m_pRight, x))
{
std::cout << proot->m_nValue << " ";
return true;
}
else
return false;
}
BinaryTreeNode *ConstructBTbyPreInOrder(int pre[], int prebegin, int mid[], int midbegin, int n)
{
if (n <= 0)
return NULL;
BinaryTreeNode *proot = CreateBinaryTreeNode(pre[prebegin]);
int index;
for (int i = midbegin; i < midbegin + n; i++)
{
if (pre[prebegin] == mid[i])
{
index = i;
break;
}
}
int k = index - midbegin;
proot->m_pLeft = ConstructBTbyPreInOrder(pre, prebegin + 1, mid, midbegin,k);
proot->m_pRight = ConstructBTbyPreInOrder(pre, prebegin+k + 1, mid, index + 1, n - k-1);
return proot;
}
BinaryTreeNode *ConstructBTbyPostInOrder(int post[], int postbegin, int mid[], int midbegin, int n)
{
if (n <= 0)
return NULL;
BinaryTreeNode *proot = CreateBinaryTreeNode(post[postbegin + n - 1]);
int index;
for (int i = midbegin;i < midbegin + n; i++)
{
if (post[postbegin + n - 1] == mid[i])
{
index = i;
break;
}
}
int k = index - midbegin;
proot->m_pLeft = ConstructBTbyPostInOrder(post, postbegin, mid, midbegin, k);
proot->m_pRight = ConstructBTbyPostInOrder(post, postbegin+k, mid, index + 1, n - k- 1);
return proot;
}
bool AncestorIter(BinaryTreeNode *proot, int x)
{
if (proot == NULL)
return false;
BinaryTreeNode *p = proot, *q = NULL;
std::stack<BinaryTreeNode*>temp;
bool flag;
do
{
while (p)
{
temp.push(p);
p = p->m_pLeft;
}
q = NULL;
flag = true;
while (!temp.empty() && flag)
{
p = temp.top();
if (p->m_nValue == x)
{
temp.pop();
while (!temp.empty())
{
std::cout << temp.top()->m_nValue << " ";
temp.pop();
}
return true;
}
else
{
if (p->m_pRight == q)
{
q = p;
temp.pop();
}
else
{
p = p->m_pRight;
flag = false;
}
}
}
} while (!temp.empty());
std::cout << std::endl;
return false;
}
主函数:main.cpp
#include "BinaryTree.h"
#include<iostream>
using namespace std;
// ====================测试代码====================
// 8
// 6 10
// 5 7 9 11
int main()
{
//===
BinaryTreeNode* pNode8 = CreateBinaryTreeNode(8);
BinaryTreeNode* pNode6 = CreateBinaryTreeNode(6);
BinaryTreeNode* pNode10 = CreateBinaryTreeNode(10);
BinaryTreeNode* pNode5 = CreateBinaryTreeNode(5);
BinaryTreeNode* pNode7 = CreateBinaryTreeNode(7);
BinaryTreeNode* pNode9 = CreateBinaryTreeNode(9);
BinaryTreeNode* pNode11 = CreateBinaryTreeNode(11);
ConnectTreeNodes(pNode8, pNode6, pNode10);
ConnectTreeNodes(pNode6, pNode5, pNode7);
ConnectTreeNodes(pNode10, pNode9, pNode11);
//===============二叉树的基本操作运算==================
//输出二叉树===
//PrintTree(pNode8);
//查找结点===
//int findnode = 10;
//BinaryTreeNode *findres = FindNode(pNode8, findnode);
//if (findres) cout << findres->m_nValue << endl;
//二叉树的高度===
//int btheight = BinaryTreeHeight(pNode8);
//cout << "二叉树的高度:" << btheight << endl;
//===============二叉树的遍历-递归版=================
//前序遍历===
//PreOrder(pNode8);cout << endl;
//中序遍历===
//InOrder(pNode8); cout << endl;
//后序遍历===
//PostOrder(pNode8); cout << endl;
//===============二叉树的遍历-迭代版=================
//前序遍历===
//PreOrderIter(pNode8);
//中序遍历===
//InOrderIter(pNode8);
//后序遍历===
//PostOrderIter(pNode8);
//================二叉树的层次遍历===================
//LevelOrder(pNode8);
//==================二叉树的其他操作运算--递归版======
//二叉树的结点个数===
//int nodecount = NodeCount(pNode8);
//cout << nodecount << endl;
//二叉树的所有叶子结点===
//AllLeavesNode(pNode8);
//二叉树的复制===
//BinaryTreeNode *other = NULL;
//CopyOneToAnthor(pNode8, other);
//PrintTree(other);
//DestroyTree(other);
//由数组转化为二叉树===
//const int n = 7;
//int a[n] = { 8, 6, 10, 5, 7, 9, 11 };
//BinaryTreeNode *proot = NULL;
//ConvertArrayToBT(a, n, 0, proot);
//PrintTree(proot);
//DestroyTree(proot);
//x所在的层
//int x = 0;
//int height = Level(pNode8, x, 1);
//cout << height << endl;
//输出x的祖先结点
//int x = 8;
//Ancestor(pNode8, x);
//由前序和中序构造二叉树===
const int n = 7;
int pre[n] = { 8, 6, 5, 7, 10, 9, 11 };
int mid[n] = { 5, 6, 7, 8, 9, 10, 11 };
int post[n] = { 5, 7, 6, 9, 11, 10, 8 };
//BinaryTreeNode *proot1 = ConstructBTbyPreInOrder(pre, 0, mid, 0, n);
//PrintTree(proot1);
//DestroyTree(proot1);
//由后序和中序构造二叉树===
//BinaryTreeNode *proot2 = ConstructBTbyPostInOrder(post, 0, mid, 0, n);
//PrintTree(proot2);
//DestroyTree(proot2);
//====================二叉树的其他操作运算--迭代版======
//输出x的祖先结点
//int x = 9;
//AncestorIter(pNode8, x);
//销毁二叉树===
DestroyTree(pNode8);
}