您的位置:首页 > 其它

二叉树操作总结

2013-02-21 17:32 267 查看
关于树及二叉树的基本定义就不多说,下面以BST为例,介绍一下二叉树的创建、遍历以及一些简单的算法。

首先是结点定义及初始化:

struct node{
int data;
node* lchild;
node* rchild;
};

node* init_node(int value){
node* new_node = new node();
new_node->data = value;
new_node->lchild = NULL;
new_node->rchild = NULL;
return new_node;
}


还是那句话,初始化别放在main函数中,关于这个问题,程序员们肯定说这还用说吗,但对于没写过程序的人(例如我)来说,可能根本就不会想到这是个问题。

关于BST,咱都知道,即root->data > root->lchild->data && root->data < root->rchild->data; 那么在加入新结点时只需要根据这个条件找到它的父节点即可。

所以,找到要插入结点的父节点并插入的方法如下:

node* search_parent(node* root,int value){
node* parent = root;
node* current_node = root;
while(current_node!=NULL){
parent = current_node;
if(current_node->data >= value){
current_node = current_node->lchild;
}else{
current_node = current_node->rchild;
}
}
return parent;
}
void add_node(node* root,int value){
node* new_node = init_node(value);
node* parent = search_parent(root,value);
if(value >= parent->data){
parent->rchild = new_node;
}else{
parent->lchild = new_node;
}
}


好,下面初始化一个BST并且遍历它,关于二叉树的遍历方式,前序中序后序

node* init_BST(int* arr,int len){
node* root = init_node(9);
for(int i=0;i<len;i++){
add_node(root,arr[i]);
}
return root;
}
void inorder(node* root){
if(root){
inorder(root->lchild);
cout<<root->data<<" ";
inorder(root->rchild);
}
}
void preorder(node* root){
if(root){
cout<<root->data<<" ";
preorder(root->lchild);
preorder(root->rchild);
}
}
void postorder(node* root){
if(root){
postorder(root->lchild);
postorder(root->rchild);
cout<<root->data<<" ";
}
}


下面来考虑几个有关二叉树的算法

1.求叶子结点数

叶子结点既没有左子树也没有右子树,因此只要满足current->lchild==NULL && current->rchild==NULL; 则count+=1;

总的叶子结点数 = l_叶子结点数 + r_叶子结点数,代码如下:

int leaf_node(node* root){
node* current_node = root;
if(current_node==NULL)
return 0;
else if(current_node->lchild==NULL && current_node->rchild==NULL){
cout<<endl<<"leaf node is "<<current_node->data<<" ";
return 1;
}
else
return leaf_node(current_node->lchild)+leaf_node(current_node->rchild);
}


2.求树的高度

数据结构书中给出的算法是

if(root == NULL)

  height = 0;

else

  height = max(height(root->lchild),height(root->rchild))+1

由于是求子树的高度,要知道height(root),只需知道height(root->lchild)和height(root->rchild),同理,要知道height(root->lchild)和height(root->rchild),只需知道它们各自子树的高度,依次类推。这样的想法,用递归来实现,递归退出的条件为urrent_node->lchild==NULL && current_node->rchild==NULL

int height(node* root){
int lheight,rheight;
node* current_node = root;
if(current_node==NULL)
return 0;
else if(current_node->lchild==NULL && current_node->rchild==NULL)
return 1;
else{
lheight = height(current_node->lchild);
rheight = height(current_node->rchild);
}
int height = lheight>=rheight?lheight+1:rheight+1;
cout<<endl<<"height of child tree "<<height<<" ";
return height;
}


3.查找一个结点

这个也不难想,current_node->data = value,

bool search_node(node* root,int value){
node* current_node = root;
bool has = false;
if(root==NULL){
return false;
}else if(root->data==value){
return true;
}else{
if(root->lchild!=NULL){
has = search_node(root->lchild,value);
}
if(!has && root->rchild!=NULL){
has = search_node(root->rchild,value);
}
}
return has;
}


4.求结点之间的最大路径

这道题目需要考虑三种情况:

(1)root->lchild!=NULL && root->rchild!=NULL

那么距离最远的两个结点一定分别位于左右子树

(2)当没有左子树或者没有右子树时,最大距离可能为某一结点到root根结点之间的距离

(3) 也可能为子树内部的两个结点之间的距离

我第一次写这个题目时,没有考虑那么多,只写出了第一种情况下的代码,如下:

int distance_differentChild(node* root){
int distance;
if((root==NULL)||(root->lchild==NULL&&root->rchild==NULL))
return 0;
else{
distance = height(root->lchild)+height(root->rchild);
}
return distance;
}


当然了,还需要考虑缺了一个子树时的情况,代码如下:

int distance_compare(node* root){
int distance_passroot = height(root);
int distance_notpassroot = distance_differentChild(root);
return distance_passroot>=distance_notpassroot?distance_passroot:distance_notpassroot;
}


最后,汇总一下求最远距离的代码:

int distanceBetweenTwoNodes(node* root){
int distance;
if((root==NULL)||(root->lchild==NULL&&root->rchild==NULL))
return 0;
else if(root->lchild==NULL || root->rchild==NULL){
if(root->lchild!=NULL){
distance = distance_compare(root->lchild);
}
if(root->rchild!=NULL){
distance = distance_compare(root->rchild);
}
}
else{
distance = distance_differentChild(root);
}
return distance;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: