端午节假期的最后一天,天气凉爽,我下午该回学校了。原本,我昨天就该写下二叉树的博文,但是由于在二叉树删除这块的功能实现不尽人意,所以我推迟了,希望将其改进后再进行记录。早上趁着清醒,我如愿地改进了二叉树的删除功能,特此记录想法的美好瞬间。
1、二叉树的基本概念
二叉树的特点是每个结点至多有二棵子树,并且子树之间有左右之分。
2、二叉查找树的操作
<span style="font-size:14px;">#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
struct tree_node
{
int key;
struct tree_node *left;
struct tree_node *right;
};</span>
1)查找
步骤:step1:判断root(根地址)是否为空,若不是则顺序执行;
step2:判断根节点的key值是否等于查找值value,若相等则return NULL,否则选择左子树或者右子树进行查找;
代码:
<span style="font-size:14px;">struct tree_node* search(struct tree_node *root, int value)
{
struct tree_node *p;
while(root!=NULL)
{
p=root;
if (root->key==value)
{
return NULL;
}
root=(root->key<value) ? root->right:root->left;
}
//not found
return p;
}</span>
2)插入
步骤:step1:判断根节点是否为空,若满足则令新节点为根,否则执行step2;
step2:在以root为根节点这棵树上进行value的查找,判断返回值。若为空,则说明value已存在不需要插入,return。否则继续执行;
step3:将返回的
指针
节点的key值与value进行比较,若value>key,则将其连接至指针节点的右子树,反之亦然。
代码:
<span style="font-size:14px;">void insert_Tree(struct tree_node *root, int value)
{
struct tree_node *s;
//initialize insert node
struct tree_node *p=new struct tree_node;
p->key=value;
p->left=NULL;
p->right=NULL;
if (!root)
{
root=p;
return;
}
else
{
s=search(root,value);
if (s==NULL)
{
cout<<"do not need to insert"<<endl;
delete p;
return;
}
if (s->key>value)
{
s->left=p;
}
else
{
s->right=p;
}
return;
}
}</span>
3)中序遍历
<span style="font-size:14px;">int print_value(int data)
{
cout<<data<<endl;
return 1;
}
int print_tree_inorder(struct tree_node *root)
{
if (root)
{
if (print_tree_inorder(root->left))
if (print_value(root->key))
if(print_tree_inorder(root->right))
return 1;
return 0;
}
else
{
return 1;//边界
}
}</span>
4)删除
对二叉树删除这部分,其实比较复杂,接下来通过图解来说明删除的几种情况。
图1 删除根节点,根节点的右子树的左子树不空
图2 删除节点6,节点6的右子树的左子树为空
对于删除的其余情况参加代码。代码如下:
<span style="font-size:14px;">struct tree_node* delete_tree_node(struct tree_node *root, int value)
{
struct tree_node *c_root;
struct tree_node *p=root;
struct tree_node *s,*parent;
if (NULL==p)
{
fprintf(stderr,"the deleting value is %d not found\n",value);
return NULL;
}
if (p->key==value)
{
/* only a root, no children */
if (!p->left && !p->right)
{
root=NULL;
free(p);
return NULL;
}
else if (!p->right)
{
root=p->left;
free(p);
return root;
}
else if (!p->left)
{
root=p->right;
free(p);
return root;
}
else
{
/* tree has both children */
s=p->right;
if (!s->left)
{
s->left=p->left;
root=s;
free(p);
return root;
}
else
{
/* look for the last not empty left node in left subtree */
while(s->left)
{
parent=s;
s=s->left;
}
parent->left=s->right;
s->right=p->right;
s->left=p->left;
root=s;
free(p);
return root;
}
}
}
else if (p->key<value)
{
if((c_root=delete_tree_node(p->right,value))!=NULL )
{
root->right=c_root;//将返回后的结点与根结点重新连接
return root;
}
else
return NULL;
}
else if (p->key>value)
{
if((c_root=delete_tree_node(p->left,value))!=NULL)
{
root->left=c_root;
return root;
}
else
return NULL;
}
// return;
}</span>
3、测试主程序及结果
<span style="font-size:14px;">int main()
{
struct tree_node *root,*t_root;
root=new struct tree_node;
root->key=8;
root->left=NULL;
root->right=NULL;
insert_Tree(root,6);
insert_Tree(root,20);
insert_Tree(root,5);
insert_Tree(root,7);
insert_Tree(root,22);
insert_Tree(root,15);
insert_Tree(root,17);
insert_Tree(root,16);
insert_Tree(root,18);
print_tree_inorder(root);
cout<<"\nAfter deleting, the tree is:"<<endl;
t_root=delete_tree_node(root,8);//delete root node
// t_root=delete_tree_node(root,6);
print_tree_inorder(t_root);
return 0;
}</span>
删除节点6的实验结果: