二叉树操作
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树操作相关的知识,希望对你有一定的参考价值。
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
struct BiTNode //二叉树结点类型
int data; //数据
int tem1,tem2; //辅助数据(实习题不用)
BiTNode *left; //左子树指针
BiTNode *right; //右子树指针
;
BiTNode *Tree; //本程序操作的二叉树根指针
const max=100;
int elem[max]; //存放原始数据
//从键盘输入个数和随机数种子,在数组elem中生成指定个数的数据,供其他程序使用,0表示数据结束
void init0(int list[]);
//在本程序所在的位置生成文本文件Map.txt,其中显示以Tree为根指针的二叉树
void showBinTree(BiTNode *Tree);
//从键盘输入个数和随机数种子,以Tree为根指针,生成指定结点个数的二叉树,供其他程序使用
BiTNode *init1();
//主函数,显示功能菜单(包括生成二叉树、显示二叉树),键盘选择后执行对应功能
void main()
#include "BinT.h"
/*
2、用递归方法分别先序、中序、后序遍历以Tree为根指针的二叉树。
3、编写递归算法,计算二叉树中叶子结点的数目。
4、编写递归算法,计算二叉树的深度。
5、编写递归算法,将二叉树中所有结点的左、右子树相互交换。
6、使用数组elem中的随机数序列(以0表示结束,不包括0),生成以Tree为根指针的二叉排序树。
7、在以Tree为根指针的二叉排序树中查找结点。
8、从以Tree为根指针的二叉排序树中删除结点(适用各种位置的结点)。
9、不用递归,先序遍历以Tree为根指针的二叉树。
提示:用数组 BiTNode *stack[max] 构成堆栈,利用这个堆栈实现功能。
10、用凹入表示法的表示以Tree为根指针的二叉树,例如:
// 324
// 123
// 746
// 690
// 567
11、用广义表表示以Tree为根指针的二叉树,例如
// (324(123(746(),()),(690(),())),(567(),()))
12、对以Tree为根指针的二叉树,从根结点开始,逐层从左到右输出各结点的数据。
提示:用数组 BiTNode *queue[max] 构成队列,利用这个队列实现功能
提高题:
13*、根据Huffman编码原理,使用数组elem中的随机数序列(以0表示结束,不包括0)作为结点的权重,生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度。
14*、(1)随机生成二叉树。 (2)生成并保存先(后)序、中序输出序列。 (3)按照保存的一对输出序列恢复出二叉树。(4)生成先(后)序输出序列。
*/
源文件名:P3.cpp
功能:二叉树操作
*/
#include <iostream.h>
#include <iomanip.h>
#include <conio.h>
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <stack>
using namespace std;
typedef int DataType;
const max=100;
typedef struct
DataType data[max];
int top;
SeqStack;
struct BiTNode //二叉树结点类型
int data; //数据
int tem1,tem2; //辅助数据(实习题不用)
BiTNode *left; //左子树指针
BiTNode *right; //右子树指针
;
BiTNode *Tree; //本程序操作的二叉树根指针
int elem[max]; //存放原始数据
//从键盘输入个数和随机数种子,在数组elem中生成指定个数的数据,供其他程序使用,0表示数据结束
void init0(int list[]);
//在本程序所在的位置生成文本文件Map.txt,其中显示以Tree为根指针的二叉树
void showBinTree(BiTNode *Tree);
//从键盘输入个数和随机数种子,以Tree为根指针,生成指定结点个数的二叉树,供其他程序使用
BiTNode *init1();
//主函数,显示功能菜单(包括生成二叉树、显示二叉树),键盘选择后执行对应功能
void Preorder(BiTNode *Tree);//先序遍历
void Inorder(BiTNode *Tree); //中序遍历
void Postorder(BiTNode *Tree); //后序遍历
int leafs(BiTNode *Tree); //总叶子数
void swap(BiTNode *Tree); //交换左右子树
int depth(BiTNode *Tree); //计算二叉树的深度
void search(BiTNode *T); //查找结点
BiTNode *CreatBST(int A[],int n) ;/
void insert(BiTNode *Tree);
int ELEM(int A[]);/
void del(BiTNode *Tree);/
void preorderl(BiTNode *Tree);/
void main()
//int list[max];
char choice;
while (1)
system("cls");
cout << "\n\n\n\n";
cout << "\t\t 二叉树操作 \n";
cout << "\t\t======================================";
cout << "\n\n";
cout << "\t\t a:生成二叉树 \n";
cout << "\t\t b:显示 \n";
cout << "\t\t c:先序遍历 \n";
cout << "\t\t d:中序遍历 \n";
cout << "\t\t e:后序遍历 \n";
cout << "\t\t f:计算二叉树中叶子结点的数目 \n";
cout << "\t\t g:计算二叉树的深度 \n";
cout << "\t\t h:左、右子树相互交换 \n";
cout << "\t\t i:构建以Tree为根指针的二叉排序树 \n";
cout << "\t\t j:查找结点 \n";
cout << "\t\t k:删除结点 \n";
cout << "\t\t l:不用递归,先序遍历以Tree为根指针的二叉树。 \n";
cout << "\t\t m:凹入表示法的表示以Tree为根指针的二叉树 \n";
cout << "\t\t n:用广义表表示以Tree为根指针的二叉树 \n";
cout << "\t\t o:从根结点开始,逐层从左到右输出各结点的数据 \n";
cout << "\t\t p:生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度 \n";
cout << "\t\t 0:退出 \n";
cout << "\n";
cout << "\t\t请选择:" << flush;
choice = getch();
system("cls");
switch(choice)
case 'a':
Tree=init1();
break;
case 'b':
showBinTree(Tree);
break;
case 'c':
cout<<"先序遍历:"<<endl;
Preorder(Tree);
cout <<flush;
getch();
break;
case 'd':
cout<<"中序遍历:"<<endl;
Inorder(Tree);
cout <<flush;
getch();
break;
case 'e':
cout<<"后序遍历:"<<endl;
Postorder(Tree);
cout <<flush;
getch();
break;
case 'f':
cout<<"二叉树的总叶子结点数为:"<<leafs(Tree)<<endl;
cout <<flush;
getch();
break;
case 'g':
cout<<"二叉树的深度为:"<<depth(Tree)<<endl;
cout <<flush;
getch();
break;
case 'h':
swap(Tree);
cout<<"交换成功!"<<endl;
showBinTree(Tree);
cout <<flush;
getch();
break;
case 'i':
init0(elem);
Tree=CreatBST(elem,ELEM(elem));
break;
case 'j':
cout<<"请输入要查找的元素:";
search(Tree);
cout <<flush;
getch();
break;
case 'k':
cout<<"请输入需要删除的元素:";
del(Tree);
Tree=CreatBST(elem,ELEM(elem));
showBinTree(Tree);
cout <<flush;
getch();
break;
case 'l':
break;
case 'm':
break;
case 'n':
break;
case 'o':
break;
case 'p':
break;
case 'q':
break;
case 'r':
break;
case '0':
exit(0);
#include "BinT.h"
//公用的等待函数
void wait()
cout << "\n\n请按任意键继续" << flush;
getch();
void Preorder(BiTNode *T)//先序遍历
if(T)
cout<<T->data<<" ";
Preorder(T->left);
Preorder(T->right);
void Inorder(BiTNode *T)//中序遍历
if(T)
Inorder(T->left);
cout<<T->data<<" ";
Inorder(T->right);
void Postorder(BiTNode *T)//后序遍历
if(T)
Postorder(T->left);
Postorder(T->right);
cout<<T->data<<" ";
int leafs(BiTNode *T)//总叶子数
if(T==NULL)
return 0;
if((T->left==NULL) && (T->right==NULL))
return 1;
else
return leafs(T->left) + leafs(T->right);
int depth(BiTNode *T)//计算二叉树的深度
int n1,n2;
if(!T)
return 0;
else
n1=depth(T->left);
n2=depth(T->right);
if(n1>n2)
return n1+1;
else
return n2+1;
void swap(BiTNode *T)//交换左右子树
BiTNode *Q;
if(T)
Q = T->left ;
T->left = T->right ;
T->right = Q;
swap(T->left);
swap(T->right);
int InsertBST(BiTNode *&T,int k)
if (T==NULL)
T=(BiTNode *)malloc(sizeof(BiTNode));
T->data=k;
T->left=T->right=NULL;
return 1;
else if (k==T->data)
return 0;
else if (k<T->data)
return InsertBST(T->left,k);
else
return InsertBST(T->right,k);
BiTNode *CreatBST(int A[],int n)
BiTNode *bt=NULL;
int i=0;
while (i<n)
InsertBST(bt,A[i]);
i++;
return bt;
void search(BiTNode *T)//查找结点
int x,count=0;
cin>>x;
while(T!=NULL)
if(T->data==x)
count++;break;
else if(x<T->data)
T=T->left;
else
T=T->right;
if(count>0)
cout<<"查找到该元素。"<<endl;
else
cout<<"不存在该元素。"<<endl;
int ELEM(int A[])
int i;
for(i=0;elem[i]!=0;i++);
return i;
void del(BiTNode *T)
int x,i=0,j=-1;
cin>>x;
for(i;elem[i]!=0;i++)
if(elem[i]==x)
j=i;break;
if(j>=0)
for(j;elem[j]!=0;j++)
elem[j]=elem[j+1];
cout<<"删除成功。"<<endl;
else
cout<<"删除元素不存在。"<<endl;
void preorderl(BiTNode T) //不用递归,先序遍历以Tree为根指针的二叉树
SeqStack s;
s.top= -1;
while(T||s.top!= -1) //当前处理的子树不为空或栈不为空则循环
while(T)
printf(“%c”,T->data);
s.top++;
s.data[s.top]=T;
T=T->left;
If(s.top>-1)
T=pop(&s);
T=T->right;
/*
2、用递归方法分别先序、中序、后序遍历以Tree为根指针的二叉树。
3、编写递归算法,计算二叉树中叶子结点的数目。
4、编写递归算法,计算二叉树的深度。
5、编写递归算法,将二叉树中所有结点的左、右子树相互交换。
6、使用数组elem中的随机数序列(以0表示结束,不包括0),生成以Tree为根指针的二叉排序树。
7、在以Tree为根指针的二叉排序树中查找结点。
8、从以Tree为根指针的二叉排序树中删除结点(适用各种位置的结点)。
9、不用递归,先序遍历以Tree为根指针的二叉树。
提示:用数组 BiTNode *stack[max] 构成堆栈,利用这个堆栈实现功能。
10、用凹入表示法的表示以Tree为根指针的二叉树,例如:
// 324
// 123
// 746
// 690
// 567
11、用广义表表示以Tree为根指针的二叉树,例如
// (324(123(746(),()),(690(),())),(567(),()))
12、对以Tree为根指针的二叉树,从根结点开始,逐层从左到右输出各结点的数据。
提示:用数组 BiTNode *queue[max] 构成队列,利用这个队列实现功能
提高题:
13*、根据Huffman编码原理,使用数组elem中的随机数序列(以0表示结束,不包括0)作为结点的权重,生成赫夫曼树,以及赫夫曼编码,计算平均带权径长度。
14*、(1)随机生成二叉树。 (2)生成并保存先(后)序、中序输出序列。 (3)按照保存的一对输出序列恢复出二叉树。(4)生成先(后)序输出序列。
*/ 参考技术A 推荐你看下严蔚敏的数据结构,上面的算法都有。
二叉树的操作
二叉树的比较与相加
二叉树的克隆操作
克隆操作就是将当前的二叉树复制一份出来,其复制接口的返回值为堆空间中的一颗新二叉树,这个二叉树的地址是不一样的,但是这颗树的其他属性和数据元素在对应位置都是相当的,接口的定义如下所示
sharedPointer <BTree<T>> clone()const
设计思路
在堆空间里面先创建一个二叉树结点出来,然后把数据元素复制到新创建的二叉树结点中,接下来就递归的克隆左子树和右子树,然后指定左右子树的父亲,也就是新创建出来的结点,递归公式如下
return NULL; node == NULL
clone(node)
n = NewNode();
n->value = node->value;
n->left = clone(node->left); node != NULL
n->right = clone(node->right);
代码实现
protected:
BTreeNode<T>* clone(BTreeNode<T>* node)const
BTreeNode<T>* ret = NULL;
if(node!=NULL)
ret = BTreeNode<T>::NewNode();
if(ret!=NULL)
ret->value = node->value;
ret->l_pointer = clone(node->l_pointer);
ret->r_pointer = clone(node->r_pointer);
if(ret->l_pointer!=NULL)
ret->l_pointer->parent = ret;
if(ret->r_pointer!=NULL)
ret->r_pointer->parent = ret;
else
THROW_EXCEPTION(NoEnougMemoryException,"No EnoungMemory");
return ret;
public:
SharedPointer < BTree<T> > clone()const
BTree<T>* ret = new BTree<T>();
if(ret!=NULL)
ret->m_root = clone(root());
else
THROW_EXCEPTION(NoEnougMemoryException,"No enoug memory to malloc");
return ret;
二叉树比较操作
二叉树比较操作就是判断两个二叉树中的数据元素是否对应相等,就是两个树的根节点数据元素,左子树,右子树对应相等,因为引入了比较操作,所以我们得重载比较操作符,可以看出比较也是一个递归调用的过程,递归公式如下所示
return true; lh==rh
return false; lh == 0&& rh!=0
retunr false; lh != 0&& rh==0
equal(rh,lh)
lh->value==rh->value&&
equal(lh->left,rh->left)&& lh!=0&&rh!=0
equal(lh->right,rg->right)
代码:
protected:
bool operator ==(const BTree<T>* btree)
return equal(this->root(),btree->root());
bool operator !=(const BTree<T>* btree)
return !(this==btree);
public:
bool equal(BTreeNode<T>* lh,BTreeNode<T>* rh)
if(lh==rh)
return true;
else if((lh!=NULL)&&(rh!=NULL))
return (lh->value==rh->value)&&equal(lh->l_pointer,rh->l_pointer)&&equal(lh->r_pointer,rh->r_pointer);
else
return false;
二叉树的相加操作
相加操作就是将当前二叉树与参数btree中的数据元素在对应位置处相加,返回值为堆空间中的一颗新二叉树,当然对于二叉树来说它还有一些特殊的结点,比如上图中的2号结点,6号结点相加操作,需要将2号结点的左子树赋值结果二叉树对应结点的左子树,同样的道理2号结点的右子树也是同样的操作,将lh为根节点的二叉树与递归公式如下所示
clone(rh) lh==0&&rh!=0
add(lh,rh) clone(lh) lh!=0&&rh==0
n = NewNode();
n->value = lh->value + rh->value;
n->left = add(lh->left,rh->left); lh!=0&&rh!=0
n->right = add(lh->right,rh->rigth);
代码
protected:
BTreeNode<T>* add(BTreeNode<T>* lh,BTreeNode<T>* rh)
BTreeNode<T>* ret = NULL;
if((lh!=NULL)&&(rh==NULL))
ret = clone(lh);
else if((lh==NULL)&&(rh!=NULL))
ret = clone(rh);
else if((lh!=NULL)&&(rh!=NULL))
ret = BTreeNode<T>::NewNode();
if(ret!=NULL)
ret->value = lh->value+rh->value;
ret->l_pointer = add(lh->l_pointer,rh->l_pointer);
ret->r_pointer = add(lh->r_pointer,rh->r_pointer);
if(ret->l_pointer!=NULL)
ret->l_pointer->parent = ret;
if(ret->r_pointer!=NULL)
ret->r_pointer->parent = ret;
else
THROW_EXCEPTION(NoEnougMemoryException,"no EnougMemory Exception");
return ret;
public:
SharedPointer < BTree<T> > add(const BTree<T>& btree)
BTree<T>* ret = new BTree<T>();
if(ret!=NULL)
ret->m_root = add(root(),btree.root());
else
THROW_EXCEPTION(NoEnougMemoryException,"no EnougMemory.....");
return ret;
实验代码
int main()
BTree<int> bt;
BTreeNode<int>* n = NULL;
bt.insert(1,NULL);
n = bt.find(1);
bt.insert(2,n);
bt.insert(3,n);
n = bt.find(2);
bt.insert(4,n);
bt.insert(5,n);
n = bt.find(4);
bt.insert(8,n);
bt.insert(9,n);
n = bt.find(5);
bt.insert(10,n);
n=bt.find(3);
bt.insert(6,n);
bt.insert(7,n);
SharedPointer < BTree<int> > clonenode = bt.clone();
BTree<int> nbt;
nbt.insert(0,NULL);
n = nbt.find(0);
nbt.insert(6,n);
nbt.insert(2,n);
n = nbt.find(2);
nbt.insert(7,n);
nbt.insert(8,n);
SharedPointer < BTree<int> > r = bt.add(nbt);
int a[] = 8,9,10,13,15;
for(int i =0;i<5;i++)
TreeNode<int>* node = r->find(a[i]);
while(node)
cout<<node->value<<" ";
node = node->parent;
cout<<endl;
SharedPointer < Aarry<int> > tr = r->traversal(PreOrder);//先序遍历
for(int i =0;i<tr->length();i++)
cout<<(*tr)[i]<<" ";
cout<<endl;
//cout<<(bt==*clonenode)<<endl;
return 0;
以上是关于二叉树操作的主要内容,如果未能解决你的问题,请参考以下文章