文章目录
前言
很忙,不写前言
--------------------------- 二叉树类-------------------------
typedef struct tree
{
char val;
struct tree* left;
struct tree* right;
}Tree;
一、二叉树的先根遍历(递归/栈)
实现功能
以先根顺序遍历二叉树
ADL描述
用栈实现的非递归无adl描述
实现
1.递归
void Preorder(Tree* root)//上左右
{
if (NULL == root) {
return;
}
printf("%c ", root->val);//输出放在最前面
Preorder(root->left);
Preorder(root->right);
}
2.非递归
void NRO(Tree* root) { //树的先根遍历(栈)
stack<Tree*> s;
Tree* p = root;
while (p != NULL || s.empty() == 0) { //遍历到节点为空或栈空
while (p != NULL) {//节点不空,输出压栈,一直取左
cout << p->val<<" ";
s.push(p);
p = p->left;
}
if (s.empty() == 0) {//左取光后,栈不空则弹栈取一次其右
p = s.top();
//cout << p->val;
s.pop();
p = p->right;
}
}
cout << endl;
}
二、二叉树的中根遍历(递归/栈)
实现功能
用中根顺序遍历二叉树
ADL描述
实现
1.递归
void InOrder(Tree* root)//左上右
{
if (NULL == root) {
return;
}
InOrder(root->left);
printf("%c ", root->val);//输出放在中间
InOrder(root->right);
}
2.非递归
void NIO(Tree* root) { //树的中序遍历(栈)
stack<Tree*> s;
Tree* p = root;
while (p != NULL || s.empty() == 0) {
while (p != NULL) {
//这里不再像先根那样输出
s.push(p);
p = p->left;
}
if (s.empty() == 0) {
p = s.top();
cout << p->val<<" ";//在取右前输出就是中序遍历
s.pop();
p = p->right;
}
}
cout << endl;
}
三、二叉树的后根遍历(递归/栈)
实现功能
后根顺序遍历二叉树
ADL描述
实现
1.递归
void PostOrder(Tree* root)//左右上
{
if (NULL == root) {
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%c ", root->val);//输出放在最后
}
2.非递归
typedef pair<Tree*, int> ti;
void NPO(Tree* root) {
if (!root)return;
stack<ti> sta;
sta.push({ root, 0 });
while (sta.empty() == 0) {
ti cur = sta.top();
sta.pop();
Tree* p = cur.first;
int i = cur.second;
if (i == 0)
{//标记位为0时改成1压入,尝试压入左节点
sta.push({ p,1 });
if (p->left != NULL)
sta.push({ p->left,0 });
}
else if (i == 1)
{//标记位为1时改成2压入,尝试压入右节点
sta.push({ p,2 });
if (p->right != NULL)
sta.push({ p->right,0 });
}
//标记位为2,输出
else if (i == 2)cout << p->val << " ";
}
cout << endl;
}
四、二叉树的层序遍历
实现功能
一层一层的遍历二叉树
ADL描述
实现
void LevelOrder(Tree* root) {
if (root == NULL)return;
//进行了些许改进,令其遍历过一层后打出一个回车
queue<Tree*> que;
que.push(root);
while (!que.empty())
{
int tmp = que.size();
while (tmp--)
{
Tree* p = que.front();
que.pop();
cout << p->val << " ";
if (p->left != NULL)que.push(p->left);
if (p->right != NULL)que.push(p->right);
}
cout << endl;
}
cout << endl;
}
五、先根次序创建二叉树CBT
实现功能
参照先根遍历的方法,构建一棵二叉树,#代表NULL
ADL描述
实现
Tree* CBT() //先根次序构建二叉树
{
Tree* root;
char ch;
cin>>ch;
if (ch == '#') {//递归过程一旦读入#返回空值给上一层
return NULL;
}
else {
root = (Tree*)malloc(sizeof(Tree));
root->val = ch;//构建根节点
root->left = CBT();//构建左子树
root->right = CBT();//构建右子树
return root;
}
}
六、复制二叉树
实现功能
将一个现有的二叉树复制给另一个二叉树
ADL描述
实现
Tree* Copy_Tree(Tree* oroot)
{
if (oroot == NULL)return NULL;
Tree* nroot = (Tree*)malloc(sizeof(Tree));
nroot->val = oroot->val;//复制根节点
nroot->left = Copy_Tree(oroot->left);//复制左子树
nroot->right = Copy_Tree(oroot->right);//复制右子树
return nroot;
}
七、查找给定节点的父亲
实现功能
返回指向结点p之父亲的指针
ADL描述
实现
Tree* Find_father(Tree* root, Tree* target) {//寻找一个节点的父亲
if (NULL == root||target==NULL||target==root) {
return NULL;
}
if (root->left == target || root->right == target)return root;
Tree* left = Find_father(root->left, target);
if (left != NULL)return left;
Tree* right= Find_father(root->right, target);
if (right != NULL)return right;
}
八、查找结点
实现功能
用先根遍历在二叉树中搜索符合数据条件(item)的结点p
ADL描述
实现
Tree* Find(Tree* root, char item) {
if (root == NULL)return NULL;
if (root->val == item)return root;//查找根节点,遍历过程中一旦找到目标就返回
Tree* left = Find(root->left, item);//查找左子树
if (left != NULL)return left;
Tree* right = Find(root->right, item);//查找右子树
if (right != NULL)return right;
}
九、释放二叉树
实现功能
释放以p指向结点为根的树
ADL描述
实现
void del_Tree(Tree* root)
{
if (NULL == root) {
return;
}
del_Tree(root->left);
del_Tree(root->right);
free(root);
}
十、插入节点
实现功能
在二叉树中插入结点p,作为结点s的左儿子,s原来的左儿子成为p的左儿子
ADL描述
实现
void insert(Tree* p, Tree* s)
{//将p插入到s节点的左侧,s原来的左子树作为p左子树
if (!p || !s)return;
p->left = s->left;
s->left = p;
return;
}
十一、删除节点及其左右子树
实现功能
root指向一棵二叉树T之根,本算法从T中删除给定结点t (t是指向该结点的指针)及其左右子树;DST是DelSubTree之缩写
ADL描述
实现
void DST(Tree* root, Tree* target)
{
if (target == NULL)return;
if (target == root) { free(target); }
Tree* father = Find_father(root,target);
if (father->left == target)father->left = NULL;
if (father->right == target)father->right = NULL;
free(target);
return;
}
测试用例
int main()
{
Tree* mytree = CBT();
Preorder(mytree); cout << endl;
NRO(mytree);
InOrder(mytree); cout << endl;
NIO(mytree);
PostOrder(mytree); cout << endl;
NPO(mytree);
LevelOrder(mytree);
Tree* yourtree = Copy_Tree(mytree);
LevelOrder(yourtree);
cout << Find_father(mytree, Find(mytree, 'h'))->val<<endl;
insert(Find(mytree, 'i'), Find(yourtree, 'b'));
LevelOrder(yourtree);
DST(yourtree, Find(yourtree, 'b'));
LevelOrder(yourtree);
//输入这个试试
//a b d # # e # # c h # # i # #
}
总结
很忙,不写总结