数据结构:二叉树和二叉搜索树

二叉树创建(层序)

与层序有关的要用到队列,因此创建一个队列

Bintree creat()//二叉树层序创建(想用C++STL库的,到时候改成new)
{
	int data;
	BinTree BT,T;
	
	scanf("%d",&data);
	if(data!=0)
	{
		BT=(BinTree)malloc(sizeof(struct TNode));
		BT->data=data;
		BT->left=NULL;
		BT->right=NULL;
		q.push(data);
	}
	else return NULL;

	while(!q.empty())
	{
		T=q.front();
		scanf("%d",&data);
		if(data==0) T->left=NULL;
		else{
			T->left=(BinTree)malloc(sizeof(struct TNode));
			T->left->data=data;
			q.push(T->left)
		} 
		scanf("%d",&data);
		if(data==0) T->right=NULL;
		else{
			T->right=(BinTree)malloc(sizeof(struct TNode));
			T->right->data=data;
			q.push(T->right)
		} 
		
	}
	
	return BT;
}

输出二叉树中所有叶结点

分析:用到的知识是二叉树的遍历,在遍历的时候加条件(左子树和右子树都为空即可)

void Preorderprintleaves(BinTree BT)
{
	if(BT)
	{
		if(!BT->left&&!BT->right)
		{
			printf("%d",BT->data);
		}	
		Preorderprintleaves(BT->left);
		Preorderprintleaves(BT->right);
	}
 } 

递归求二叉树高度

分析:求二叉树高度=求左子树高度和求右子树高度中最大的那个=…=…(递推下去吧)

int getHeight(BinTree BT)
 {
 	int HL,HR,MAXH;
 	
 	if(BT)
 	{
 		HL=getHeight(BT->left);
 		HR=getHeight(BT->right);
 		MAXH=HL>HR?HL:HR;
 		return(MAXH+1);
	 }
	 else return 0;/*空树高度为0*/
 }

二叉搜索树(BST)的查找

注意返回的还是指针,指向二叉树的结点
如果发现BST为空了(查完了还没找到) 返回查找失败

typedef struct node *Bintree;
struct node{
int data;
Bintree left,right;
};

Bintree find(Bintree BST,int x)
{
   if(!BST) return NULL;
   else
   {
   	if(BST->data==x) return BST;//返回当前结点的地址
   	else if(BST->data>x) return find(BST->left,x);
   	else if(BST->data<x) return find(BST->right,x); 
   }
}

查找BST的最大最小值

方法一:递归
方法二:迭代

利用BST的性质,最小元素一定在树的最左分支的端结点上

Bintree FindMax(Bintree BST)
{
	if(!BST) return NULL;
	else if(BST->right==NULL) return BST;
	else return FindMax(BST->right);

}

Bintree findmin(Bintree BST)
{
	if(BST)
	{
	
	while(BST->left)
	{
		BST=BST->left;
	}
	return BST;
	}
}

BST的插入

操作类似于查找,必须记得分情况
原树为空,那么建一个只有一个结点的树
原树不为空,递归寻找插入的位置

最后返回的也是指针,指向插入元素的位置
(递归真是个好东西啊)

Bintree insert(Bintree BST,int x)
{
	if(!BST)
	{
		BST=(Bintree)malloc(sizeof(struct node));
		BST->data=x;
		BST->left=BST->right=NULL;
	}
	else
	{
		if(BST->data>x)
		{
			insert(BST->left,x);
		}
		else if (BST->data<x)
		{
			insert(BST->right,x);
		}
	}
	return BST;
}

二叉搜索树的插入其实还是很方便的,因为数据的插入后一定接在树下方,不影响其他结点,但是删除就相对复杂了,一个结点的删除会影响其他结点的位置

二叉搜索树的删除

三种情况
1.删除的是叶结点
2.删除的结点只有一个孩子结点
3.删除的结点有左右两颗子树,那么要转换为第二种情况:选取左子树中的最大元素或者右子树的最小元素(利用上面讲的findmax和findmin函数鸭)

Bintree delete(Bintree BST,int x)
{
	//先找到要被删除的元素
	Bintree tmp;
	if(!BST) return printf("未找到")else
	{
		if(x<BST->data) delete(BST->left,x);
		else if(x>BST->data) delete(BST->right,x);
		else if(x==BST->data)
		{
			if(BST->left&&BST->right)
			/*有两个子节点*/
			{
				tmp=findmin(BST->right);
				BST->data=tmp->data;
				/*重要过程?递归(why?如何理解?)*/
				BST->right=delete(BST->right,BST->data); 
			}
			else
			{
				tmp=BST;
				if(!BST->left)//只有右孩子
				BST=BST->right;
				else
				{
					BST=BST->left;
				} 
				free(tmp);//原来数据被删除,指针改变方向 
			}
			
		}
		
	return BST;
	} 
}
//最后返回值还是指针,指向的是删除后的结点,原来的数据不复存在 
发布了46 篇原创文章 · 获赞 13 · 访问量 3686

猜你喜欢

转载自blog.csdn.net/qq_39679772/article/details/103943831