二叉树用法

二叉树用法

目录

二叉树的创建
二叉树的遍历
二叉堆的基本用法

========================================================

一.二叉树的创建

创建二叉树(先序,中序,后序)
typedef struct node;
typedef node *tree; 
struct node
{
	char date;
	tree lchild;
	tree rchild;
};
tree bt;
void built(tree &bt) // 二维指针一不小心就出错,还是引用好 
{
	char s;
	cin >> s;
	if(s=='#')
		bt = NULL;
	else
	{
		bt = new node;
		bt -> date = s;  // 先序建立二叉树,中序,后序改一下这三行的位置 
		built(bt->lchild);
		built(bt->rchild);
	}
}

========================================================

二叉树的遍历

一.三种遍历。

void preorder(tree bt)//先序遍历,根左右。 
{
	if(bt == NULL)
		return;
	cout << bt -> date;
	preorder(bt->lchild);
	preorder(bt->rchild);
} 
void inorder(tree bt)//中序遍历,左根右。 
{
	if(bt == NULL)
		return;
	inorder(bt->lchild);
	cout << bt -> date;
	inorder(bt->rchild);
}
void poseorder(tree bt)//后序遍历,左右根。 
{
	if(bt == NULL)
		return;
	postorder(bt->lchild);
	postorder(bt->rchild);
	cout << bt->date;
}

二.依据两种遍历求第三种遍历
(无法根据先序+后序求中序)

/*
假设根节点在中序中的位置为pos,树的结点数为len 
先序, 根节点编号(0), 左子树编号(1~pos), 右子树编号(pos+1~len-1) 
中序, 左子树编号(0~pos-1), 根节点编号(pos), 右子树编号(pos+1~len-1)  
后序, 左子树编号(0~pos-1), 右子树编号(pos~len-2), 根点编号(len-1) 
*/
void q_postorder(string preorder, string inorder)//先序+中序,实现后序.
{
	int len = preorder.length();
	if(len == 0)
		return;
	if(len == 1)
	{
		cout << preorder[0];
		return;
	}
	int pos = inorder.find(preorder[0]);    //substr:字符截取函数 
	q_postorder(preorder.substr(1,pos), inorder.substr(0,pos));//后序遍历左子树;
	q_postorder(preorder.substr(pos+1,len-pos-1), inorder.substr(pos+1,len-pos-1));//后序遍历右子树,pos从0开始,所以len-pos-1 
	cout << preorder[0];
} 
void q_preorder(string inorder, string postorder) //中序+后序,实现先序.
{
	int len = postorder.length();
	if (len == 0)
		return;     
	if(len == 1)
	{
		cout << inorder[0];
		return ;
	}
	int pos = inorder.find(postorder[len-1]);
	cout << postorder[len-1]; 
	q_preorder(inorder.substr(0, pos),  postorder.substr(0, pos)); //先序遍历左子树 
	q_preorder(inorder.substr(pos+1, len-pos-1), postorder.substr(pos, len-pos-1));//先序遍历右子树 
}

========================================================

二叉堆的基本用法

二叉堆有两种操作,插入和删除。

// 小根堆,大根堆反过来。 
int heap[N];
int cnt = 0;
void push(int x)//插入堆的值 
{
	int now = cnt++;//插入节点的编号 
	while(now > 0)
	{
		int fa = (now - 1) / 2; //父亲节点的编号
		if(heap[fa] <= x)
			break; //如果顺序未颠倒,则退出循环
		heap[now] = heap[fa];
		now = fa; 
	}
	heap[now] = x;
}
int pop()
{
	int res = heap[0];
	int x = heap[--cnt];//最末尾的节点 
	int i = 0;//从根节点开始操作 
	while(i * 2 + 1 < cnt)
	{
		int lchild = 2 * i + 1;
		int rchild = 2 * i + 2;
		if(rchild < cnt && heap[rchild] < heap[lchild])
			lchild = rchild;
		if(heap[lchild] >= x) 
			break;
		heap[i] = heap[lchild];
		i = lchild; 
	}
	heap[i] = x;
	return res;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值