1.一般二叉树的存储结构
有两个指针,分别指向左右子树的根结点地址,如果子树不存在,指向NULL,称之为二叉链表
struct node
{
typename data;
node *lchild,*rchild;
};
由于二叉树建树前根节点不存在,因此其地址一般设为NULL
node *root=NULL;
新建一个值为v的结点
node *newnode(int v)
{
node *new_node=new node;
new_node->data=v;
new_node->rchild=NULL;
new_node->lchild=NULL;
return new_node;
}
找到值为x的结点修改为y
void search(int x,int y,node *root)//找到值为x的结点修改为y
{
if(root==NULL) return;
if(root->data==x) root->data=y;//找到值为x的结点修改为y
search(x,y,root->lchild);
search(x,y,root->rchild);
}
在二叉树中插入一个值为x的新结点
void insert(node* &root,int x)
/*
在二叉树中插入一个值为x的新结点,注意必须要加&,否则对root的修改无法作用到原变量上去,而search中不需要使用引用是因为它修改的是root指向的内容而非root本身
总结:如果函数中需要改变二叉树结构,那么加引用,如果只是遍历并修改当前已有结点的内容,则不需要加引用
*/
/*
对于一个待插入的结点,它在二叉树中的插入位置只有一个,否则题目就有不确定性了。
因此可以得到一个结论,该二叉树结点的插入位置就是数据域在二叉树中查找失败的位置
即递归查找的过程中根据二叉树的性质选择左右子树中的一棵进行递归,且最后到达空树(递归边界)的地方就是查找失败也是插入的位置
*/
{
if(root==NULL)
{
root=newnode(x);
return;
}
if(根据二叉树性质,x应该插在左子树)
insert(root->lchild,x);
else insert(root->rchild,x);
}
创建一个二叉树(一般会给一部分结点的值,以数组a方式存储)
void create(int a[],int n)
{
node *root=NULL;
for(int i=1;i<=n;i++)
{
insert(root,a[i]);
}
return root;
}
2.完全二叉树的特殊存储方式
这段话里面提到了两个问题:
①为什么不能从0开始存储,因为根据左结点编号为2*k=2*0=0,不满足编号规则
②为什么不需要判断右子结点,因为根据编号规则右边已经大于左边的编号了