二叉树的概念
二叉树是一棵每个节点都不能有多于两个儿子的树
有N个结点的完全二叉树的深度:
公式:K =「log2n」+1
证明:可用数学归纳法。
当n=1=2^1-1时显然。
假设当n<=2^k-1时具有n个结点的完全二叉树的深度为「log2n」+1,则
当n=2^k(以及2^k+1,…,2^(k+1)-1)时,由归纳假设知前2^k-1个结点构成深度为「log2n」+1的树,再由完全二叉树的定义知剩余的1(或2,…,2^k)个结点均填在第「log2n」+2层上(作为“叶子”),故深度刚好增加了1。
故n<=2^(k+1)-1时命题成立。证毕。
(首先最好能先从直观上理解:完全二叉树中:
第1层有1个结点;
第2层有2个结点;
第3层有4个结点;
……
第k层有2^(k-1)个结点;(前k层共有(2^k)-1个结点,故前面深度刚好是「log2(2^k-1)」+1=k-1+1=k)
第k+1层是剩余的结点。
二叉树的平均深度为
二叉树的实现
因为一个二叉树结点最多有两个儿子,所以可以直接链接到它们。树节点的声明在结构上类似于双向链表的声明。在声明中,一个结点就是由element的信息加上两个到其他结点的引用(
struct BinaryNode
{
Object element; //data in the node
BinaryNode *left; //Left child
BinaryNode *right; //Right child
}
二叉树的创建
#include<iostream>
using namespace std;
typedef struct node
{
struct node *leftChild;
struct node *rightChild;
char data;
}BiTreeNode ,*BiTree;
//————————建立二叉树——————————
void createBitree(BiTree &T)
{
char c;
cin>>c;
if('#'==c)
T==NULL;
else
{
T=new BiTreeNode;
T->data=c;
createBitree(T->leftChild);
createBitree(T->rightChild);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
BiTree T;
int numNode;
createBitree(T);
cout<<"二叉树建立完成"<<endl;
system("pause");
return 0;
}
二叉树常见问题
题目参照:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888
1)遍历:前序,中序,后序
2)结点个数:
递归解法:
(1)如果二叉树为空,节点个数为0
(2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1
3) 求二叉树的深度
递归解法:
(1)如果二叉树为空,二叉树的深度为0
(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1
4)分层遍历二叉树(按层次从上往下,从左往右)
相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点,访问,若左子节点或右子节点不为空,将其压入队列。
常见问题的程序实现
// three_order_map.cpp : 定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include<iostream>
#include<queue>
#define N 7
using namespace std;
typedef struct node
{
struct node *leftChild;
struct node *rightChild;
int data;
}BiTreeNode, *BiTree;
BiTreeNode *createNode(int i)
{
BiTreeNode * q = new BiTreeNode;
q->leftChild = NULL;
q->rightChild = NULL;
q->data = i; //1,2,3,4,5,6也可以自己输入
return q;
}
BiTree createBiTree()
{
BiTreeNode *p[N] = {NULL};
int i;
for(i = 0; i < N; i++)
{
p[i] = createNode(i + 1);
cout<<p[i]->data<<endl;
}
for(i = 0; i < N/2; i++)
{
p[i]->leftChild = p[i * 2 + 1];
p[i]->rightChild = p[i * 2 + 2];
}
return p[0];
}
int visit(BiTree T)
{
return T->data;
}
// 先序遍历
void preOrderTraverse(BiTree T)
{
if(T)
{
cout << visit(T) << " ";
preOrderTraverse(T->leftChild);
preOrderTraverse(T->rightChild);
}
}
// 中序遍历
void inOrderTraverse(BiTree T)
{
if(T)
{
inOrderTraverse(T->leftChild);
cout << visit(T) << " ";
inOrderTraverse(T->rightChild);
}
}
// 后序遍历
void postOrderTraverse(BiTree T)
{
if(T)
{
postOrderTraverse(T->leftChild);
postOrderTraverse(T->rightChild);
cout << visit(T) << " ";
}
}
//求二叉树中的结点个数
int GetNodeNum(BiTreeNode * pRoot)
{
if(pRoot == NULL) // 递归出口
return 0;
return GetNodeNum(pRoot->leftChild) + GetNodeNum(pRoot->rightChild) + 1;
}
//求二叉树的深度
int GetDepth(BiTreeNode * pRoot)
{
if(pRoot == NULL) // 递归出口
return 0;
int depthLeft = GetDepth(pRoot->leftChild);
int depthRight = GetDepth(pRoot->rightChild);
return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1);
}
//分层遍历二叉树
void LevelTraverse(BiTreeNode * pRoot)
{
if(pRoot == NULL)
return;
queue<BiTreeNode *> q;
q.push(pRoot);
while(!q.empty())
{
BiTreeNode * pNode = q.front();
q.pop();
cout<<visit(pNode); // 访问节点
if(pNode->leftChild != NULL)
q.push(pNode->leftChild);
if(pNode->rightChild != NULL)
q.push(pNode->rightChild);
}
return;
}
int main()
{
int num;
BiTree T = createBiTree(); //根节点
cout << "先序遍历:" << endl;
preOrderTraverse(T);
cout << endl << endl;
cout << "中序遍历:" << endl;
inOrderTraverse(T);
cout << endl << endl;
cout << "后序遍历:" << endl;
postOrderTraverse(T);
cout << endl << endl;
num=GetNodeNum(T);
cout<<"结点个数为 "<<num<<endl;
num=GetDepth(T);
cout<<"树的深度为 "<<num<<endl;
cout<<"层次遍历的结果为:";
LevelTraverse(T);
cout<<endl;
system("pause");
return 0;
}
由于博主的学识有限,难免会出现错误,欢迎大家在评论区批评,指正,交流,也欢迎大家对博文的内容上的继续补充