//BinaryTree.h
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
void createBinaryTree1(BinaryTreeNode** root);
void createBinaryTree2(BinaryTreeNode* &root);
BinaryTreeNode* createBinaryTree3();
void printBinaryTree(BinaryTreeNode* root);
void deleteBinaryTree(BinaryTreeNode* &root);
//BinaryTree.cpp
#include<iostream>
#include "BinaryTree.h"
#include<deque>
using namespace std;
//这里由于创建二叉树的时候有可能修改根节点的地址,因此,传入的参数是指向指针的指针。
//这里的root是二级指针,二级指针就是一级指针的地址
void createBinaryTree1(BinaryTreeNode** root)
{
char data;
cin >> data;
if ('#' == data)//输入结束标志
*root = NULL;
else
{
*root = new BinaryTreeNode();//分配新的内存
(*root)->m_nValue = data;//输入的值赋值给数的节点值
createBinaryTree1(&(*root)->m_pLeft);//递归创建左子树
createBinaryTree1(&(*root)->m_pRight);//递归创建右子树
}
}
//这是第二种建立的方式,其实和第一种没有区别。
//由于建立二叉树的时候需要修改二叉树根节点的指针,因此在这里,用指针的引用做为输入,其实和指针的指针是一样的。
//不过这样写,避免了二级指针的初始化问题,而且在内部递归的时候避免了复杂的写法。
//这可以单纯做为学习指针的练习,关于指针需要仔细体会。
void createBinaryTree2(BinaryTreeNode* &root)
{
char data;
cin >> data;
if('#'== data) //本节点
root = NULL;
else
{
root = new BinaryTreeNode();
root->m_nValue = data;
createBinaryTree2(root->m_pLeft);
createBinaryTree2(root->m_pRight);
}
}
//这是第三种形式的建立方法,很明显,和前面的两种方法都属于先序遍历建立二叉树的方法。
//但是三个函数对于指针参数的传递方法不一样,前两者可以作为引用的例子,后一种是参数返回的方法。
//由于本人C++属于菜鸟级别,因此在这里将三种形式都罗列出来,体会其区别。
BinaryTreeNode* createBinaryTree3()
{
BinaryTreeNode* pNode = NULL;
char data;
cin >> data;
if('#' != data)
{
pNode = new BinaryTreeNode();
pNode->m_nValue = data;
pNode->m_pLeft = createBinaryTree3();
pNode->m_pRight = createBinaryTree3();
}
return pNode;
}
//先序遍历打印二叉树
void printBinaryTree(BinaryTreeNode* root){
if(root != NULL){
//cout << root->m_nValue << " ";
printf("%c ",root->m_nValue);
printBinaryTree(root->m_pLeft);
printBinaryTree(root->m_pRight);
}
}
//删除树结构
void deleteBinaryTree(BinaryTreeNode* &root)
{
if(root != NULL)
{
deleteBinaryTree(root->m_pLeft);
deleteBinaryTree(root->m_pRight);
delete root;
}
}
//层序遍历打印二叉树(关键在于用队列保存树的根节点)
void printBinaryTreeInLevelOrder(BinaryTreeNode* root)
{
if(root == NULL)
return ;
std::deque<BinaryTreeNode*> dequeBinaryTreeNode;
dequeBinaryTreeNode.push_back(root);
while(!dequeBinaryTreeNode.empty())
{
BinaryTreeNode* pNode = dequeBinaryTreeNode.front();
dequeBinaryTreeNode.pop_front();
//cout << pNode->m_nValue << " ";
printf("%c ",pNode->m_nValue);
if(pNode->m_pLeft)
dequeBinaryTreeNode.push_back(pNode->m_pLeft);
if(pNode->m_pRight)
dequeBinaryTreeNode.push_back(pNode->m_pRight);
}
}
void Test1()
{
//测试输入:ABDH##I##E##CF#J##G##
// A
// / \
// B C
// / \ / \
// D E F G
// / \ \
// H I J
BinaryTreeNode** root1;
BinaryTreeNode* pNode = NULL;
root1 = &pNode;
createBinaryTree1(root1);
cout << "第一种二叉树建立形式" << endl;
printBinaryTree(*root1);
}
void Test2()
{
BinaryTreeNode* root2 = NULL;
createBinaryTree2(root2);
cout << "第二种二叉树建立形式" << endl;
printBinaryTree(root2);
}
void Test3()
{
BinaryTreeNode* root3 = NULL;
root3 = createBinaryTree3();
cout << "第三种二叉树建立形式" << endl;
printBinaryTree(root3);
cout << "二叉树层序遍历结果" << endl;
printBinaryTreeInLevelOrder(root3);
}
int main()
{
Test1();
Test2();
Test3();
system("pause");
return 0;
}
//BinaryTree.h
struct BinaryTreeNode
{
int m_nValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
};
void createBinaryTree1(BinaryTreeNode** root);
void createBinaryTree2(BinaryTreeNode* &root);
BinaryTreeNode* createBinaryTree3();
void deleteBinaryTree(BinaryTreeNode* &root);
//层序遍历打印二叉树
void printBinaryTreeInLevelOrder(BinaryTreeNode* root);
//先序遍历
void printBinaryTreeInPreOrder(BinaryTreeNode* root);
//中序遍历
void printBinaryTreeInMidOrder(BinaryTreeNode* root);
//后序遍历
void printBinaryTreeInBacOrder(BinaryTreeNode* root);
//BinaryTree.cpp
#include<iostream>
#include "BinaryTree.h"
#include<deque>
using namespace std;
//这是第三种形式的建立方法,很明显,和前面的两种方法都属于先序遍历建立二叉树的方法。
//但是三个函数对于指针参数的传递方法不一样,前两者可以作为引用的例子,后一种是参数返回的方法。
//由于本人C++属于菜鸟级别,因此在这里将三种形式都罗列出来,体会其区别。
BinaryTreeNode* createBinaryTree3()
{
BinaryTreeNode* pNode = NULL;
char data;
cin >> data;
if ('#' != data)
{
pNode = new BinaryTreeNode();
pNode->m_nValue = data;
pNode->m_pLeft = createBinaryTree3();
pNode->m_pRight = createBinaryTree3();
}
return pNode;
}
//删除树结构
void deleteBinaryTree(BinaryTreeNode* &root)
{
if (root != NULL)
{
deleteBinaryTree(root->m_pLeft);
deleteBinaryTree(root->m_pRight);
delete root;
}
}
//层序遍历打印二叉树(关键在于用队列保存树的根节点)
void printBinaryTreeInLevelOrder(BinaryTreeNode* root)
{
if (root == NULL)
return;
std::deque<BinaryTreeNode*> dequeBinaryTreeNode;
dequeBinaryTreeNode.push_back(root);
while (!dequeBinaryTreeNode.empty())
{
BinaryTreeNode* pNode = dequeBinaryTreeNode.front();
dequeBinaryTreeNode.pop_front();
//cout << pNode->m_nValue << " ";
printf("%c ", pNode->m_nValue);
if (pNode->m_pLeft)
dequeBinaryTreeNode.push_back(pNode->m_pLeft);
if (pNode->m_pRight)
dequeBinaryTreeNode.push_back(pNode->m_pRight);
}
cout << endl;
}
//先序遍历打印二叉树
void printBinaryTreeInPreOrder(BinaryTreeNode* root){
if (root != NULL){
//cout << root->m_nValue << " ";
printf("%c ", root->m_nValue);
printBinaryTreeInPreOrder(root->m_pLeft);
printBinaryTreeInPreOrder(root->m_pRight);
}
}
//中序遍历
void printBinaryTreeInMidOrder(BinaryTreeNode* root){
if (root != NULL){
printBinaryTreeInMidOrder(root->m_pLeft);
printf("%c ", root->m_nValue);
printBinaryTreeInMidOrder(root->m_pRight);
}
}
//后序遍历
void printBinaryTreeInBacOrder(BinaryTreeNode* root){
if (root != NULL){
printBinaryTreeInBacOrder(root->m_pLeft);
printBinaryTreeInBacOrder(root->m_pRight);
printf("%c ", root->m_nValue);
}
}
void Test3()
{
BinaryTreeNode* root3 = NULL;
root3 = createBinaryTree3();
//cout << "第三种二叉树建立形式" << endl;
cout << "二叉树层序遍历结果:" << endl;
printBinaryTreeInLevelOrder(root3);
cout << "二叉树先序遍历结果:" << endl;
printBinaryTreeInPreOrder(root3);
cout << endl;
cout << "二叉树中序遍历结果:" << endl;
printBinaryTreeInMidOrder(root3);
cout << endl;
cout << "二叉树后序遍历结果:" << endl;
printBinaryTreeInBacOrder(root3);
cout << endl;
}
int main()
{
//Test1();
//Test2();
Test3();
system("pause");
return 0;
}
//测试输入:ABDH##I##E##CF#J##G##
// A
// / \
// B C
// / \ / \
// D E F G
// / \ \
// H I J
参考:《剑指offer》
其他资源