本文介绍二叉树的链式存储,即用一组离散的存储空间存储二叉树,相关操作包括了对二叉树的前序(先序)、中序、后序遍历,需要用到递归的算法思想进行操作,对于非线性结构,如果想对之进行操作,少不了对它进行遍历。话不多说,我们开始操作:
先对要用的数据宏定义一下(非必要):
#define TREE_TYPE char
#define EMPTY '#'
#define END '\0'
定义一下链式二叉树的数据项,大概了解一下二叉链的构成:
//设计二叉树结点
typedef struct TreeNode
{
TREE_TYPE data;
struct TreeNode *left;
struct TreeNode *right;
}TreeNode;
下面用C语言函数写出二叉树链式存储的各种操作:
创建二叉树结点
//创建二叉树结点
TreeNode *create_tree_node(TREE_TYPE data)
{
TreeNode *node=malloc(sizeof(TreeNode));
node->data=data;
node->left=NULL;
node->right=NULL;
return node;
}
TreeNode *_create(char **str)
{
if(EMPTY==**str || END==**str) return NULL;
TreeNode *node=create_tree_node(**str);
*str+=1;
node->left=_create(str);
*str+=1;
node->right=_create(str);
return node;
}
创建二叉树
//创建二叉树
TreeNode *create_tree(char *str)
{
_create(&str);
}
先序遍历
//先序
void preorder_tree(TreeNode *root)
{
if(NULL==root) return;
printf("%c ",root->data);
preorder_tree(root->left);
preorder_tree(root->right);
}
中序遍历
//中序
void midorder_tree(TreeNode *root)
{
if(NULL==root) return;
midorder_tree(root->left);
printf("%c ",root->data);
midorder_tree(root->right);
}
后序遍历
//后序
void postorder_tree(TreeNode *root)
{
if(NULL==root) return;
postorder_tree(root->left);
postorder_tree(root->right);
printf("%c ",root->data);
}
树的高度
//树的高度
int high_tree(TreeNode *root)
{
if(NULL==root) return 0;
int lh=high_tree(root->left);
int rh=high_tree(root->right);
return lh>rh?lh+1:rh+1;
}
树的密度
//树的密度
int num_tree(TreeNode *root)
{
if(NULL==root) return 0;
return num_tree(root->left)+num_tree(root->right)+1;
}
求左子树
//求左子树
TreeNode *left_tree(TreeNode *root,TREE_TYPE data)
{
if(NULL==root) return NULL;
if(data==root->data&&root->left) return root->left;
TreeNode *left=left_tree(root->left,data);
TreeNode *right=left_tree(root->right,data);
return left==NULL?right:left;
}
求右子树
//求右子树
TreeNode *right_tree(TreeNode *root,TREE_TYPE data)
{
if(NULL==root) return NULL;
if(data==root->data&&root->right) return root->right;
TreeNode *left=right_tree(root->left,data);
TreeNode *right=right_tree(root->right,data);
return left==NULL?right:left;
}
求根节点
//求根结点
TreeNode *root_tree(TreeNode *root,TREE_TYPE data)
{
if(NULL==root) return NULL;
if(data==root->data) return root;
TreeNode *left=root_tree(root->left,data);
TreeNode *right=root_tree(root->right,data);
return left==NULL?right:left;
}
插入
//插入
bool insert_tree(TreeNode *root,TREE_TYPE pdata,TREE_TYPE data)
{
TreeNode *node=create_tree_node(data);
if(NULL==root) return false;
if(pdata==root->data)
{
if(NULL==root->left)
{
root->left=node;
return true;
}
else if(NULL==root->right)
{
root->right=node;
return true;
}
else return false;
}
if(insert_tree(root->left,pdata,data)) return true;
if(insert_tree(root->right,pdata,data)) return true;
}
删除
//删除
bool del_tree(TreeNode *root,TREE_TYPE data)
{
if(NULL==root) return false;
if(root->left!=NULL&&data==root->left->data)
{
free(root->left->left);
free(root->left->right);
root->left=NULL;
return true;
}
if(root->right!=NULL&&data==root->right->data)
{
free(root->right->left);
free(root->right->right);
root->right=NULL;
return true;
}
if(del_tree(root->left,data)) return true;
if(del_tree(root->right,data)) return true;
}
销毁
//销毁
void destroy_tree(TreeNode *root)
{
del_tree(root,'G');
del_tree(root,'D');
del_tree(root,'C');
del_tree(root,'E');
del_tree(root,'F');
del_tree(root,'B');
del_tree(root,'A');
free(root);
}
二叉树的链式存储大致运算就这些,下面我们可以调用函数测试一下:
int main(int argc,const char* argv[])
{
TreeNode *root=create_tree("ACD#G###BF##E##");
preorder_tree(root);
printf("\n");
midorder_tree(root);
printf("\n");
postorder_tree(root);
printf("\n");
printf("%d\n",high_tree(root));
printf("%d\n",num_tree(root));
TreeNode *left=left_tree(root,'B');
printf("%c\n",left->data);
TreeNode *right=right_tree(root,'D');
printf("%c\n",right->data);
if(insert_tree(root,'C','Z')) preorder_tree(root);
printf("\n");
TreeNode *r=root_tree(root,'D');
printf("%c\n",r->data);
if(del_tree(root,'Z')) preorder_tree(root);
printf("\n");
if(del_tree(root,'G')) preorder_tree(root);
printf("\n");
destroy_tree(root);
preorder_tree(root);
return 0;
}
over