二叉树的实现

查找和插入的实现

伪代码

查找和插入的实现都用了递归的思想遍历左右子树。

/*查找*/
SearchBST(bt,k){
    if(bt是空||bt.key等于k)
        return bt;
    if(bt.key大于k)
        return SearchBST(bt.lchild,k) //遍历左子树
    else
        return SearchBST(bt.rchild,k) //遍历右子树
}

/*插入*/
insertBST(bt,k){
    if(bt是空)
    {
        初始化bt; //创建bt新节点,并将bt的左右孩子都置为NULL
        bt->key=k;
    }
    else if(k等于bt.key) return 0; //表明bt树已存在k这个结点
    else if(k小于bt.key) return insertBST(bt->lchild, k); //遍历左子树
    else return insertBST(bt->lchild, k); //遍历右子树

}

/*创建BST树*/
CreateBST(bt)
{
    cin>>n>>a; //控制台获取树结点的个数n,和n个数存入数组a
    while(i小于n)       //i=0,从a[0]开始创建树bt
    {
        insertBST(bt,a[i]); //调用插入函数创建结点
        i++; 
    }
    return bt; //创建完成返回树bt
}

代码实现

/*查找*/
BSTNode* SearchBST(BSTNode* bt, Keytype k)
{
	if (bt == NULL || bt->key == k)
		return bt;
	if (k < bt->key)
		return SearchBST(bt->lchild, k);
	else
		return SearchBST(bt->rchild, k);
}
/*创建*/
int insertBST(BSTNode*& bt, Keytype k)
{
	if (bt == NULL)
	{
		bt = new BSTNode;
		bt->key = k;
		bt->lchild = bt->rchild = NULL;
		return 1;
	}
	else if (k == bt->key)
		return 0;
	else if (k < bt->key)
		return insertBST(bt->lchild, k);
	else 
		return insertBST(bt->rchild, k);
}
BSTNode* CreateBST(Keytype a[], int n)
{
	BSTNode* bt = NULL;
	int i = 0;
	while (i < n)
	{
		insertBST(bt,a[i]);
		i++;
	}
	return bt;
}

创建BST树并中序输出结果

运行演示

待生成的二叉排序树的结点为:50 30 80 20 40 90 10 25 35 85 23 88,个数为12,中序排序结果为:10 20 23 25 30 35 40 50 80 85 88 90。

运行结果正确。

完整代码代码

#include<iostream>
using namespace std;
typedef int Keytype;
typedef int InfoType;
typedef struct node
{
	Keytype key;
	InfoType data;
	struct node* lchild, * rchild;
}BSTNode;
/*创建*/
int insertBST(BSTNode*& bt, Keytype k)
{
	if (bt == NULL)
	{
		bt = new BSTNode;
		bt->key = k;
		bt->lchild = bt->rchild = NULL;
		return 1;
	}
	else if (k == bt->key)
		return 0;
	else if (k < bt->key)
		return insertBST(bt->lchild, k);
	else 
		return insertBST(bt->rchild, k);
}
BSTNode* CreateBST(Keytype a[], int n)
{
	BSTNode* bt = NULL;
	int i = 0;
	while (i < n)
	{
		insertBST(bt,a[i]);
		i++;
	}
	return bt;
}

/*中序输出*/
void InOrder(BSTNode *b)
{
	if (b != NULL)
	{
		InOrder(b->lchild);
		cout << b->key
			<< ' ';
		InOrder(b->rchild);
	}
	else return;
}
int main()
{
	BSTNode* bt;
	int len,i=0;
	Keytype a[50];
	Keytype k;
	memset(a, '0', sizeof(a));   //初始化数组
	cout << "输入待生成的二叉排序树的结点个数:" << endl;
	cin >> len;
	cout << "输入二叉排序树结点:" << endl;
	while (i<len)
	{
		cin >> a[i];
		i++;
	}
	cout << "中序遍历二叉排序树的结果为:" << endl;
	bt = CreateBST(a, len);
	InOrder(bt);
	return 0;
}

删除结点的实现

思路

删除的结点的情况分为两种:

  1. 待删除的结点只有左子树或只有右子树
  2. 待删除的结点既有左子树也有右子树

针对情况一,若结点只有左子树,只需将待删除的结点的左子树代替待删除结点的位置;若结点只有右子树,只需将待删除的结点的右子树代替待删除结点的位置。并释放删除结点的内存空间。

针对情况二,待删除的结点既有左子树又有右子树,找到起中序遍历结果的前驱结点的key值替代待删除的结点的key值,并释放删除前驱结点的内存空间。(所提到的前驱结点即为待删除结点的左子树的最右结点)

伪代码

/*删除*/
DeleteBST(bt,k)
{
    if(bt为空) return 0;//bt为空树,删除结点失败
    else{
        if(k小于bt.key) return DeleteBST(bt->lchild,k);//递归遍历左子树,找到待删除的结点
        else if(k大于bt.key) return DeleteBST(bt->rchild,k);//递归遍历右子树,找到待删除的结点
        else   //找到该结点了,进行删除操作
        {
            if(bt.lchild为空)
            {
                q=bt; //q指向待删除结点
                bt=bt->rhild;
                free(q); //释放结点内存
            }
            else if(bt.rchild为空)
            {
                 q=bt; //q指向待删除结点
                bt=bt->lhild;
                free(q); //释放结点内存
            }
            else      //该节点左右孩子都有
            {
                DeleteBST_LR(bt, bt->lchild); //调用函数
            }
        }
    }
}
/*结点有左右子树的删除*/
DeleteBST_LR(p,r)    //p为删除的结点,r为p的左结点
{
	if (r->rchild不为空)
		DeleteBST_LR(p, r->rchild);  //递归遍历找到p结点左子树的最右结点
	else     //找到左子树的最右结点,即前驱结点
	{
		p->key = r->key;   //将待删除结点的key值换为前驱结点的key值
		q = r;   
		r = r->lchild; 
		free(q);   //释放前驱结点的内存空间
	}
}

具体代码

/*结点有左右子树的删除*/
void DeleteBST_LR(BSTNode* p, BSTNode*& r)    //p为删除的结点,r为p的左结点
{
	BSTNode* q;
	if (r->rchild != NULL)
		DeleteBST_LR(p, r->rchild);  //找到p结点左子树的最右下结点
	else
	{
		p->key = r->key;
		q = r;
		r = r->lchild;
		free(q);
	}
}
/*删除*/
int  DeleteBST(BSTNode*& bt, Keytype k)
{
	if (bt == NULL) return 0;//bt为空树,删除失败返回0
	else {
		if (k < bt->key)return DeleteBST(bt->lchild, k);
		else if (k > bt->key)return DeleteBST(bt->rchild, k);
		else {
			BSTNode* q;
			if (bt->lchild == NULL) {
				q = bt;
				bt = bt->rchild;
				free(q);
			}
			else if (bt->rchild == NULL)
			{
				q = bt;
				bt = bt->lchild;
				free(q);
			}
			else {
				DeleteBST_LR(bt, bt->lchild);
			}
			return 1;
		}
	}
}

运行结果展示

创建二叉排序树“50 30 80 20 40 90 10 25 35 85 23 88”后,删除前中序遍历结果为:10 20 23 25 30 35 40 50 80 85 88 90,删除结点80后,中序遍历结果为10 20 23 25 30 35 40 50 85 88 90。

运行结果正确。

posted @ 2020-04-19 01:16  AJAJAJAJAJAJ  阅读(210)  评论(0编辑  收藏  举报