搜索二叉树(插入,删除,遍历)

C++  , windwo , VS2017实现搜索二叉树 , 插入 , 删除 ,遍历 基本操作

//define_1.h 文件 对结构体的定义

template <class T>
struct  Node {
	int date;
	Node <T> * lCHILD;
	Node <T> * rCHILD;
};

template < class T >
class Tree {
public:
	void Insert(int e );
	void Delete(int e);
	int  Show(Node<T>*rOOT);
	Node <T> *Get_root();
	Tree();
	Node <T> *rOOT;
private:
	
	
};

1 . 插入  ,

    1.1  如果插入队首 ,直接将生成的模块进行插入 ,

    1.2  否则则根据数的大小(如果大于结点,则遍历结点的左子树否则遍历结点的右子树)一直到一个结点为空时

    1.3  进行生成结点的对空间点进行赋值 (找到空节点的爸爸 , 将它爸爸的儿子赋给生成的结点)

template <class T>
void Tree<T>::Insert(int e) {
    Node<T>*temp = new Node<T>;
    if (temp == NULL) {
        cout << "内存分配失败" << endl;
        exit(1);
    }
    temp->date = e;
    temp->lCHILD = NULL;
    temp->rCHILD = NULL;
    if (rOOT == NULL)
    {
        rOOT = temp;
        return;
    }
    Node<T>*x = rOOT;
    Node<T>*y = x;
    //根据值的大小找到合适的位置进行插入
    while (x != NULL) {
        y = x;
        if (x->date > e)
            x = x->lCHILD;
        else 
            x = x->rCHILD;
    }
    //找到合适位置的父节点,进行比较插入
    if (temp->date < y->date)
        y->lCHILD = temp;
    else
        y->rCHILD = temp;
    
}

2 删除

   2.1 如果需要删除的结点存在左/右结点 , 则将左/右结点的值(不包括内存地址)赋给需要删除结点,free 掉左/右结点的空间

   2.2.1 如果需要删除的结点的左右结点同时存在,则将右结点的值(不包括内存地址)赋值非需要删除的结点,free掉右结点的空间

    2.2.2 查找到删除结点右结点的最左结点,将删除结点左结点赋值给最刚才找到的最左结点,free掉删除结点的左结点

template <class T>
void Tree<T>::Delete(int e) {
    bool Left = 1;//设置标志位,如果访问左结点置为1,否则置为零
    Node<T>*x = rOOT;
    Node<T>*y = x;
    //如果为空,不能删除,退出
    if (x == NULL)
        exit(1);
    
    //找到元素
    while (x->date != e) {
        y = x;
        if (x->date > e){
            x = x->lCHILD;
            Left = 1;
        }
        else {
            x = x->rCHILD;
            Left = 0;
        }    
    }
    //如果要对某个内存的值进行操作,必须申请一个空间,然后将需要操作的地址赋给这个空间,才能进行操作
    Node<T>*temp = new Node<T>;
    temp= (Left == 1 ? (x ==rOOT ? rOOT : y->lCHILD) : y->rCHILD); //如果是根节点则删除根节点否则删除存在子树的结点
    Node<T>*temp_2;//用来存储交换结点
    //需要删除元素的左结点或者右结点为空
    if (x->lCHILD == NULL || x->rCHILD == NULL) {
        
        temp_2= (x->lCHILD == NULL)? x->rCHILD : x->lCHILD;    //删除结点存在的子结点
        temp->date = temp_2->date;
        temp->lCHILD = temp_2->lCHILD;
        temp->rCHILD = temp_2->rCHILD;
//        free((x->lCHILD == NULL) ? x->rCHILD : x->lCHILD);
    }
    else {
        Node<T>*low = x->rCHILD;    //用于找到删除结点右子树的最左端
        temp_2 = low;                //指向最左端的父节点(或本身),用于插入
        while (low != NULL) {
            temp_2 = low; 
            low = low->lCHILD;
        }
        low = new Node<T>;
        temp_2->lCHILD = low;
        low->date = x->lCHILD->date, low->lCHILD = x->lCHILD->lCHILD, low->rCHILD = x->lCHILD->rCHILD;//赋值
        temp->date = x->rCHILD->date;
        temp->lCHILD = x->rCHILD->lCHILD;
        temp->rCHILD = x->rCHILD->rCHILD; 
        free(x->rCHILD);
    }
}

3 遍历

template <class T>
int Tree<T>::Show(Node<T>*Bi) {
	if (Bi == NULL)
	{
		return 0;
	}
	else
	{
		cout << Bi->date << "--->";
		Show(Bi->lCHILD);
		Show(Bi->rCHILD);
	}
	return 0;
}

4 . 测试用例

   插入 3 ,4                删除3

    插入  3 , 2 , 4      删除3

Tree<int>l ;//初始化
int a;
a = 3;
l.Insert(a);//插入3
int b = 4;
l.Insert(b);//插入4
l.Insert(2);//插入2
l.Show(l.rOOT);
cout << endl;
l.Delete(3); //删除3
l.Show(l.rOOT);
return 0;



    

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值