正文

我所理解的二杈树022005-12-28 11:09:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/goal00001111/8938.html

分享到:

       二杈排序树 所谓二杈排序树,指的是一棵空二杈树,或者是一棵具有如下特性的非空二杈树: 1。若它的左子树非空,则左子树上所有结点的值均小于根结点的值; 2。若它的右子树非空,则右子树上所有结点的值均大于根结点的值; 3。左,右子树本身又各是一棵二杈排序树。        二杈排序树的基本操作包括二杈排序树的查找,生成(插入)和删除。        二杈排序树的查找:        在二杈排序树b中查找x的过程为: 1。若b是空树,则搜索失败,否则 2。若x等于b的根结点的数据域之值,则查找成功;否则 3。若x小于b的根结点的数据域之值,则搜索左子树;否则       4。搜索右子树 btree* search(btree *b, ElemType x) {        if(b == NULL)               return NULL;        if(b->data == x)               return b;        if(b->data > x)               return search(b->lchild);        else              return search(b->rchild); } 二杈排序树的生成(插入)        先讨论向一个二杈排序树b中插入一个结点s的算法: 1。若b是空树,则将s所指结点作为根结点插入,否则 2。若s->data等于b的根结点的数据域之值,则什么也不做,或者在结构中增添一个标记,表示该结点 数据出现的次数;否则 3。若s->data小于b的根结点的数据域之值,则把s所指结点插入到左子树中;否则       4。把s所指结点插入到右子树中 void insert(btree **b, btree *s) {        if(*b == NULL)               *b = s;        else if((*b)->data == s->data)//不做任何插入操作               ;        else if((*b)->data > s->data)//把s所指结点插入到左子树中          insert(&((*b)->lchild), s);        else               //把s所指结点插入到右子树中          insert(&((*b)->rchild), s);    }       生成二杈排序树的过程是先有一个空树b,然后向该空树插入一个个结点实现的,因此, 根据用户输入的一系列正整数(以-1为结束标志)生成一棵二杈排序树的函数如下: void Creat(btree *b) {        ElemType x;        btree *s;               b = NULL;        do        {               scanf("%d", &x);               s = (btree*)malloc(sizeof(btree));               if(s == NULL)               {                      puts("wrong");                      exit(1);               }               s->data = x;               s->lchild = s->rchild = NULL;               insert(&b, s);  //插入一个结点s        } while(x != -1); }   或者直接一个函数搞定: btree* insert(btree *b, char x) {        if(b == NULL)        {               b = (btree*)malloc(sizeof(btree));               if(b == NULL)               {                      puts("wrong");                      exit(1);               }               b->data = x;   //putchar(x);               b->lchild = b->rchild = NULL;        }        else if(b->data == x)//不做任何插入操作               ;        else if(b->data > x)//把s所指结点插入到左子树中           b->lchild = insert(b->lchild, x);        else               //把s所指结点插入到右子树中           b->rchild = insert(b->rchild, x);        return b;   }          二杈排序树的删除:        删除二杈排序树b中一个数据域为x的结点的方法有两种。        第一种过程如下: 1。首先查找到数据域为x的结点p。 2。若p有左子树,找到其左子树的最右边的叶子结点r,用该叶子结点r来替代p,把r的左孩子 作为r的父亲的右孩子。 3。若p没有左子树,直接用p的右孩子取代它。   第二种过程如下: 1。首先查找到数据域为x的结点p。 2。若p有左子树,用p的左孩子取代它;找到其左子树的最右边的叶子结点r,把p的右子树作为r 的右子树。 3。若p没有左子树,直接用p的右孩子取代它。        两种方法各有优劣,第二种操作简单一点点,但均衡性不如第一种,因为它将结点p的右子树 全部移到左边来了。下面将以第一种思路编写代码。 void delnode(btree *b, ElemType x) {        btree *p, *prep, *r, *prer; //p和r指向待比较的结点,prep和prer分别指向它们的前驱结点               p = b;        prer = prep = NULL;        while(p != NULL && p->data != x)//查找数据域为x的结点p        {               if(x < p->data)               {                      prep = p;                      p = p->lchild;               }               else               {                      prep = p;                      p = p->rchild;               }        }        if(p == NULL)               printf("No find!\n");        else if(p->lchild != NULL) //被删结点有左子树        {               r = p->lchild;   //r指向其左子树               while(r->rchild != NULL)//搜索左子树的最右边的叶子结点r               {                      prer = r;                      r = r->rchild;               }               if(prer != NULL)//若r不是p的左孩子,把r的左孩子作为r的父亲的右孩子                      prer->rchild = r->lchild;               r->rchild = p->rchild; //被删结点p的右子树作为r的右子树               if(prep == NULL) //若p为根结点,直接删除根结点               {                      b = r;                      free(p);               }               esle if(p == prep->lchild)//若p为prep的左孩子,把r作为prep的左孩子               {                      prep->lchild = r;                      free(p);               }                   esle   //若p为prep的右孩子,把r作为prep的右孩子               {                      prep->rchild = r;                      free(p);               }            }        else        {               if(prep == NULL)               {                      b = p->rchild;                      free(p);               }               esle if(p == prep->lchild)               {                      prep->lchild = p->rchild;                      free(p);               }                   esle               {                      prep->rchild = p->rchild;                      free(p);               }            } } 

阅读(3123) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册