(数据结构第一题)删除相关子树算法
思路:二叉树
描述
构造二叉链表表示的二叉树:按先序次序输入二叉树中结点的值,'#'字符表示空树,构造二叉链表表示的二叉树T,编写算法完成:对于树中每一个值为X的结点,删去以它为根的子树,并释放相应的空间(说明:二叉树结点值为单字符,且树中可能出现值重复的结点)。
输入格式
第一行输入先序次序二叉树中结点
第二行输入一个要删除的结点值
输出格式
第一行输出删除后的二叉树先序遍历的序列(不输出空树)
第二行输出删除后的二叉树中序遍历的序列(不输出空树)
输入样例
ABDCG####E##CF###
C
输出样例
ABDE
DBEA
图例
法一 数组模拟二叉树
思路:
本题解通过数组代替链表来模拟二叉树。
变量含义:
st[N]
用来存先序遍历
的值,be[N]
用来存中序遍历
的值
st1
用来表示先序数组st的长度
,be1
用来表示中序数组be的长度
flag 用来判断该树是否被删除。flag == 0 ,表示该树可以正常进行,没有被删除
flag == 1 ,表示该子树已经被删除,继续进行遍历
,但是结果不计入st[N]和be[N]两个数组
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;
const int N = 1e5 + 10;
char st[N], be[N];
string str;
int st1,be1;//st1用来表示先序数组st的长度,be1用来表示中序数组be的长度
char a;
int cnt;
void dfs(int flag)
{
if(str[cnt]=='#')//当遇到了#,表示空子树,不用在进行遍历
{
cnt++;//去处理‘#’
return ;
}
if(str[cnt] == a) flag = 1;
char t = str[cnt++];
if(!flag)st[st1++] = t;//先序遍历就是把结果保存在两个dfs()之前
dfs(flag);//左子树
if(!flag)be[be1++] = t;//中序遍历就是把结果保存在两个dfs()中间
dfs(flag);
}
int main()
{
cin>>str>>a;
dfs(0);
for(int i = 0; i< st1; i++) cout<<st[i];
cout<<endl;
for(int i =0 ;i <be1; i ++) cout<<be[i];
cout<<endl;
return 0;
}
法二 链表实现(标准做法)
思路:用链表生成二叉树,并进行操作
在CreateBiTree函数中,使用递归的方式构建二叉树。首先输入一个字符,如果该字符为#,则表示当前子树为空树,返
回空指针。否则,创建一个新的结点,并将该字符作为结点的值,然后递归构建左子树和右子树,最后返回根结点的指针>。
在preorder和inorder函数中,实现了二叉树的先序遍历和中序遍历。在遍历过程中,判断当前结点的值是否等于给定的
字符c,如果是,则将该结点的左右孩子指针设为NULL
,从而删除
以该结点为根的子树
。否则,输出当前结点的值
,并递归遍历左子树和右子树。在main函数中,首先调用CreateBiTree函数构建二叉树,然后输入一个字符c,调用preorder和inorder函数分别进行先序>遍历和中序遍历,并输出删除子树后的遍历结果。
#include "stdio.h"
#include <iostream>
#include "malloc.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
using namespace std;
typedef char ElemType;
typedef struct BiTNode{
ElemType data;
struct BiTNode *lchild,*rchild;//左右孩子指针
} BiTNode,*BiTree;
Status CreateBiTree(BiTree &T) { // 算法6.4
// 按先序次序输入二叉树中结点的值(一个字符),’#’字符表示空树,
// 构造二叉链表表示的二叉树T。
char ch;
scanf("%c",&ch);
if (ch=='#') T = NULL;
else {
if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR;
T->data = ch;// 生成根结点
CreateBiTree(T->lchild);// 构造左子树
CreateBiTree(T->rchild); // 构造右子树
}
return OK;
} // CreateBiTree
Status preorder(BiTree T,char c)
{
if(!T)
{
return 0;
}
else
{
if(T->data == c)
{
T->lchild = NULL;
T->rchild = NULL;
}
else
{
cout << T->data;
}
preorder(T->lchild,c);
preorder(T->rchild,c);
}
return 1;
}
Status inorder(BiTree T,char c)
{
if(!T)
{
return 0;
}
else
{
inorder(T->lchild,c);
if(T->data == c)//
{
T->lchild = NULL;
T->rchild = NULL;
}
else
{
cout << T->data;
}
inorder(T->rchild,c);
}
return 1;
}
int main() //主函数
{
char c;
BiTree T;
CreateBiTree(T);
cin >> c;
preorder(T,c);
cout << "\n";
inorder(T,c);
}//main