二叉树(BinaryTree)的建立和遍历

//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》

其他资源

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值