关于二叉树的创建:
这里有个问题,就是二叉树,就不能想1中讲的那样,建立两个链表,一个孩子链表,一个组织链表,因为二叉树的孩子是分左右的,这个顺序不能搞混,所以就直接是在每个二叉树的结点中设置两个指针,分别指向左右孩子,这样就可以了,但是又有一个问题随之而来,那就是如何定位??这个问题唐老师给了一个很形象的解决办法,“指路”就是说,当你到了陌生的地方,别人给你指路,然后你会按照指的路去一步一步走,同样的,在想二叉树里插入元素的时候,自己可以设定一个路标,然后按照路标的指示一直走下去即可。
然后是二叉树的插入, 这个函数还要有一个特殊的参数,就是当你插入某个结点元素n后,该树可能是插在某个结点m的后面,而m的后面原先也有元素,当你插入后,原先的那些元素树时放在你插入的元素n的做树后面,还是右树后面呢,这个就需要这个特殊的参数了。
然后是二叉树的遍历:分为前序遍历,中序遍历,后序遍历还有层次遍历。
现在先展示一下插入函数,如何通过用指示来寻找这个函数的:
//左边的孩子
#define Child_L 0
//右边的孩子
#define Child_R 1
//这个是指向树的根节点的头
//包含着指向二叉树的根的指针,和该二叉树的结点数目
typedef struct _tag_BTreeList BTreeList;
struct _tag_BTreeList
{
BTreeNode* root;
int count;
};
插入元素函数如下:
//这里node是数据元素 pos则是路标,按照路标就可以找到 count则是计数
//这里可能有人会问,都有指标了为什么还用count呢 比如pos=0x00 你的意思是插在根节点的左边
//如果没有count 你怎么判断你这个pos已经移动完了呢 所以有必要加个count
//flag则是将插入结点后面的元素插在该元素的左边还是右边
int Tree_Insert(BTree* tree, BTreeNode* node, BTPos pos, int count, int flag)
{
BTreeList* btree = (BTreeList*)tree;
int ret = (btree != NULL) && (node != NULL);
if( ret )
{
int i = 0;
int p = -1;
//设置一个保存孩子的结点
BTreeNode* current = btree->root;
BTreeNode* parents = NULL;
//先将新结点的两个孩子指针初始化
node->left = NULL;
node->right = NULL;
//此循环为了找到相应的孩子节点
while( (count>0) && (current != NULL) )
{
p = pos&1;
pos = pos>>1;
//保存父亲结点
parents = current;
if( p == Child_L )
{
current = current->left;
}
else if( p = Child_R )
{
current = current->right;
}
count--;
}
if( parents != NULL )
{
if( p == Child_L )
{
parents->left = node;
}
else if( p == Child_R )
{
parents->right = node;
}
}
//如果两个都不是 那么插入的应该是树的根
else
{
btree->root = node;
}
//将插入结点后面的元素 连接到新的节点处
if( flag == Child_L )
{
node->left = current;
}
else if( flag == Child_R )
{
node->right = current;
}
btree->count++;
}
return ret;
}
删除函数:(这里主要注意的是count没删除一个元素的时候,可能count减小的值并不是1 因为删除的元素后面可能还会有元素)
BTreeNode* Tree_Delete(BTree* tree, BTPos pos, int count)
{
BTreeList* btree = (BTreeList*)tree;
BTreeNode* ret = NULL;
if(btree != NULL)
{
int i = 0;
int p = -1;
//设置一个保存孩子的结点
BTreeNode* current = btree->root;
BTreeNode* parents = NULL;
//此循环为了找到相应的孩子节点
//这里不要忘了加上 current != NULL 很容易弄丢
while( (count>0) && (current != NULL) )
{
p = pos&1;
pos = pos>>1;
//保存父亲结点
parents = current;
if( p == Child_L )
{
current = current->left;
}
else if( p = Child_R )
{
current = current->right;
}
count--;
}
if(parents != NULL)
{
if( p == Child_L )
{
parents->left = NULL;
}
else if( p == Child_R )
{
parents->right = NULL;
}
}
//删除的的根节点
else
{
btree->root = NULL;
}
//这里不要忘了count减小的值不是1 因为删除的元素他的后面可能还会有元素
btree->count = btree->count - recursive_count(current);
ret = current;
}
return ret;
}