6-12 二叉搜索树的操作集 (30分)

/**
    头文件、宏定义与自测主函数

**/
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<stack>

#define MAXSIZE 11
#define ERROR -1
#define NotFound 0;


using namespace std;

typedef int ElementType;
typedef struct TNode *Position;
typedef Position BinTree;
struct TNode{
    ElementType Data;
    BinTree Left;
    BinTree Right;
};


BinTree Insert( BinTree BST, ElementType X );
BinTree Delete( BinTree BST, ElementType X );
Position Find( BinTree BST, ElementType X );
Position FindMin( BinTree BST );
Position FindMax( BinTree BST );





//层次遍历,用于自测
void LevelorderTraversal(BinTree BT){
    if(!BT)
        return;

    //队列,简化起见这里没有应用循环队列
    BinTree q[1000];
    int front = 0;
    int rear = 1;
     //根结点入队
    q[0] = BT;

    //计数变量用于判断本层是否遍历完
    //已经遍历结点个数
    int _count = 0;
    //下层结点总数,初始为根节点1
    int nextCount = 1;
    //工作指针
     BinTree temp;

    //队列不为空
    while(front<rear){
        //计数
        _count++;
        //出队
        temp = q[front++];
        printf("%d ",temp->Data);
        //左右子孩子入队
        if(temp->Left)
            q[rear++] = temp->Left;
        if(temp->Right)
            q[rear++] = temp->Right;

        //判断本层结点是否遍历完
        if(_count==nextCount){
            cout<<endl;
            //计数器清零
            _count=0;
            //计算下层结点数量
            nextCount = rear-front;
        }
    }
}


int main(){
    int tree_array[]={5,8 ,6, 2 ,4, 1 ,0 ,10, 9, 7};
    int d[]={5 ,7 ,0 ,10 ,3};
    BinTree f = NULL;
    for(int i = 0 ; i<10 ;i++){
        f = Insert(f,tree_array[i]);
    }
    int k = 2;
    LevelorderTraversal(f);
    for(int i = 0 ;i <5 ;i++){
        f = Delete(f,d[i]);
        cout<<"=========="<<i+1<<"=========: "<<d[i]<<endl;

        LevelorderTraversal(f);
    }
    return 0;
}

查找类函数

//查找
Position Find( BinTree BST, ElementType X ){
    if(!BST)
        return NULL;
    if(BST->Data==X)
        return BST;
    //往左边找
    BinTree outL = Find(BST->Left,X);
    //往右边找
    BinTree outR = Find(BST->Right,X);

   return outL?outL:outR;
}


//查找最大
Position FindMax(BinTree BST){
    if(!BST)
        return NULL;
    //最右边的结点
    if(!BST->Right)
        return BST;
    //往右找即可
    return FindMax(BST->Right);
}

//查找最小
Position FindMin(BinTree BST){
    if(!BST)
        return NULL;
    //最左边的结点
    if(!BST->Left)
        return BST;
    //往左找即可
    return FindMin(BST->Left);

}

 插入函数,注意递归的设计

//向二叉排序树中插入,递归
BinTree Insert(BinTree BST, ElementType X){
    if(!BST){
        //新建一个结点
        BinTree t = (BinTree)malloc(sizeof(struct TNode));
        t->Left = t->Right = NULL;
        t->Data = X;
        BST = t;
    }//缩小问题规模,转向考虑左右子树
    else if(BST->Data>X)
        BST->Left = Insert(BST->Left,X);
    else if(BST->Data<X)
        BST->Right = Insert(BST->Right,X);
    //若等号成立元素存在,不用处理
    return BST;
}

//向二叉排序树中插入,非递归
BinTree Insert(BinTree BST, ElementType X){
    //先新建一个结点
    BinTree t = (BinTree)malloc(sizeof(struct TNode));
    t->Left = t->Right = NULL;
    t->Data = X;
    //为空则直接返回新结点指针
    if(!BST)
        return t;

    //否则找到合适的位置
    BinTree work = BST;
    //记录待插入位置的双亲
    BinTree parent = BST;
    while(work){
        //维护双亲
        parent = work;
        if(work->Data>X)
            //待插入位置
            work = work->Left;
        else if(work->Data<X)
           work = work->Right;
        else//存在相同值则不插入
            return BST;
    }
    //待插入结点为双亲的左/右孩子
    if(parent->Data>X)
        parent->Left = t;
    else
        parent->Right = t;
    return BST;
}

 

 删除函数,有三种情况。待删除结点:

1.为叶子结点:直接删除

2.为单分支结点:用子树的根取代待删除结点

3.为双分支结点:与有序后继(中序遍历的后继即右子树中最小/左的结点)交换元素,转换为删除后继所在结点即第1或第2种情况

//删除二叉排序树结点,递归
BinTree Delete( BinTree BST, ElementType X ){
    if(!BST)
        printf("Not Found\n");
    else if(BST->Data==X){
        //1.左右双分支结点
        if(BST->Left&&BST->Right){
            //右子树中最小(左)为后继
            BinTree rear = FindMin(BST->Right);
            //不涉及待删除结点元素值的操作,交换过程可简化成单向赋值
            BST->Data = rear->Data;
            //在右子树中删除后继
            BST->Right = Delete(BST->Right,rear->Data);
        //2.单支与叶子可归纳如下,删除叶子时下式中BST赋值为空即删除了叶子
        }else
            BST = BST->Left?BST->Left:BST->Right;
    //递归
    }else{
        if(BST->Data>X)
            BST->Left = Delete(BST->Left,X);
        else
            BST->Right = Delete(BST->Right,X);
    }
    return BST;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一些VC 数据结构操作类代码,各个类文件说明:array.h:安全数组,可自动增长大小(随机访问,但扩充时效率低)   linkedlist.h: 普通链表(可随机访问,但访问效率低)   dclinkedlist: 双向循环链表(不可随机访问,但插入、遍历的效率都比普通链表高)   hashtable.h:哈希表(使用键值标识元素,键值一样的元素即认为相等,需重载 == 运算符并由用户定义哈希函数)   binstree.h: 二叉搜索树(需重载 == 和 < 运算符),二叉树二叉树也可用于创建普通树)结点,构造函数,初始化结点的数据和指针域,对于空子树,将其指针域赋值为 NULL   avltree.h: AVL 树(需重载 == 和 < 运算符)   如果要存储合(元素不可重复)并快速查找,最佳的是 binstree.h(二叉搜索树)。   如果要存储二维或更高维的表格,最佳的是 hashtable.h(哈系表)。   AVL 树的插入成本非常高(删除函数也没有实现),但 AVL 的搜索效率极高,所以适用于在程序开始前初始化程序中经常要用到的合,一般应用二叉搜索树已经足够了。   以上代码都是作者照书上改写的,并未经过严格测试,如果使用过程中发现任何问题、源代码错误或可改进的地方,非常欢迎来信与我讨论。电子邮件地址:[email protected]   作者会根据各位所发现的问题不断改进各类并增加新的数据结构,使其更加完善。   参考书目:   《数据结构-C 语言描述》William Ford William Topp 著   《计算机程序设计艺术》DONALD E.KNUTH 著

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值