二叉树的创建
typedef struct Bitree {
char data;
struct Bitree* lchild;//创建左孩子结点
struct Bitree* rchild;//创建右孩子结点
}BiNode;
//利用拓展二叉树(#虚节点)
BiTree *createBiTree(BiNode *bt) {//前序建立
char c;
cin >> c;
if (c == '#')//空树
bt = NULL;
else
{
bt = new BiTree;//创建一个结点
bt->data = c;
bt->lchild = createBiTree(bt->lchild);//将递归创建左孩子的结果赋给bt的左孩子
bt->rchild = createBiTree(bt->rchild);
/*不可以这样递归建立二叉树(无法建立节点之间的连接关系)
createBiTree(bt->lchild);
createBiTree(bt->rchild);
}
return;
}
*/
}
return bt;//返回树的地址
}
主函数:
BiTree* T = NULL;
BiTree* root = createBiTree(T);//main函数也是获取root
创建方式二
//利用C++指针的引用(可以建立起节点间的联系)
BiTree::BiTree(){
Creat(root);
}
//只要bt的值发生改变,就会影响实际传入值root
void BiTree::Creat(BiNode* &bt) {//注意bt是指针类型
char c;
cin >> c;
if (c == '#')//空树
bt = NULL;
else
{
bt = new BiTree;//创建一个结点
bt->data = c;
Creat(bt->lchild);
Creat(bt->rchild);
}
return;
}
二叉树的遍历
1.前序遍历
void preOrder(BiTree* bt) {
if (bt == NULL) {
return ;
}
else {
cout << bt->data << " ";
preOrder(bt->lchild);
preOrder(bt->rchild);
}
}
2.层序遍历
void LeverOrder(BiTree* root)
{
if(root == NULL){
return ;
}
queue.enQueue(root);//根节点入队
while(!queue.isEmpty()){
q=queue.deQueue();//出队
cout<<q->data+" ";
if(q->lchild!=NULL){//左孩子入队
queue.enQueue(q->lchild);
}
if(q->rchild!=NULL){//右孩子入队
queue.enQueue(q->rchild);
}
}
}
应用
计算二叉树的深度
二叉树的深度是树中节点的最大层次,是左右子树深度的较大者加1。
int GetTreeDeep(BiTree T)
{
if(T==NULL){
return 0;
}else{
a = GetTreeDeep(T->lchild);
b = GetTreeDeep(T->rchild);
return (a>b)?(a+1):(b+1);
//return max(a+1,b+1);
}
}
复制二叉树
复制二叉树就是利用已有的一棵二叉树复制得到另外一棵与其完全相同的二叉树。根据二又树的特点,复制步骤如下:若二叉树不空,则首先复制根结点,这相当于二又树先序遍历算法中访问根结点的语句;然后分别复制二叉树根结点的左子树和右子树、这相当于先序遍历中递归遍遍历左子树和右子树的语句。
typedef struct BiTNode {
char data;
struct BiTNode * lchild,*rchild;
}BiTNode ,*BiTree;
void Copy(BiTree T, BiTree &NewT)//注意BiTree是指针类型
{
if(T==NULL){//空树,递归结束
NewT=null;
return;
}
else{
NewT=new BiTNode;
NewT->data=T->data;
Copy(T->lchild, T->lchild);
Copy(T->rchild, T->rchild);
}
}
统计二叉树中节点的个数
int NodeCount(BiTree T)//BiTree是指针类型
{
if(T == NULL)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
//否则节点的个数为左子树的节点个数+右子树的节点个数+1
}
求叶子节点数量(度为0)
int get_leaf_number(BTreeNode *root)
{
if(root == NULL)
return 0;
if(root->lchild == NULL && root->rchild == NULL)
return 1;
return (get_leaf_number(root->lchild) + get_leaf_number(root->rchild));
}
求度为1节点数量
两种写法,一种是最后return。
int NodeCount(BiTree T){
if(T==NULL) {
return 0;
}
//找到度为1的节点:只有右孩子 或 只有左孩子
if(T->lchild==NULL&&T->rchild!=NULL || T->rchild==NULL&&T->lchild!=NULL){
return 1+NodeCount(T->lchild)+NodeCount(T->rchild);//返回1(节点自己)+递归左孩子 或 右孩子
}
else{//该节点的度为2,继续向下递归
return NodeCount(T->lchild)+NodeCount(T->rchild);
}
}
int NodeNumber(BiTree T)
{
int sum=0;
if(T==NULL){
return 0;
}
if(T!=NULL){
if( (T->lchild==NULL&&T->rchild!=NULL) ||(T->lchild!=NULL&&T->rchild==NULL)){
sum=1+NodeNumber(T->lchild)+NodeNumber(T->rchild);
}
else{
sum=NodeNumber(T->lchild)+NodeNumber(T->rchild);
}
}
return sum;
}
求度为2节点数量
int NodeNumber(BiTree T)
{
int sum=0;
if(T==NULL){
return 0;
}
if(T!=NULL){
if((T->lchild!=NULL)&&(T->rchild!=NULL)){//左右孩子都有就可以
sum=1+NodeNumber(T->lchild)+NodeNumber(T->rchild);
}
else{
sum=NodeNumber(T->lchild)+NodeNumber(T->rchild);
}
}
return sum;
}
删除二叉树
void Release(BiTree T)
{
if(T!=NULL){
Release(T->lchild);
Release(T->rchild);
delete(T);
}
}
待续:线索二叉树与哈夫曼编码…