二叉树用法
目录
二叉树的创建
二叉树的遍历
二叉堆的基本用法
========================================================
一.二叉树的创建
创建二叉树(先序,中序,后序)
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;
}