一、二叉树常见操作
1. 二叉树的定义
二叉树的定义:
二叉树是一种树形结构:
特点是与每个节点关联的子节点至多有两个(可为0,1,2)
每个节点的子节点有关联位置关系
定义:
二叉树是节点的有限集合,该集合或为空集,或由一个根元素和两棵不相交的二叉树组成(递归定义)
二叉树的两棵子树分别称为它的左子树和右子树
二叉树的5种基本形态:
typedef char ElemType;
typedef struct BtNode
{
BtNode *leftchild; //左子树
BtNode *rightchild; //右子树
ElemType data; //数据
}BtNode,*BinaryTree;
//创建一个节点
BtNode* buynode()
{
BtNode *s=(BtNode *)malloc(sizeof(BtNode));
if(s== NULL)
{
exit(1);
}
memset(s,0,sizeof(BtNode));
return s;
}
//释放一个节点
void FreeNode(BtNode *s)
{
free(s);
}
2. 二叉树的创建(两种办法)
- 递归:递归创建一颗二叉树 (树的数据直接由键盘传入,后序和中序之间关系太弱,用先序遍历创建一棵树,将空用“#”代替)
BtNode* CreatTree1()
{
BtNode *s=NULL;
ElemType data;
cin >>data;
if(data !='#')
{
s=buynode();
s->data=data;
s->left=CreatTree1();
s->right=CreatTree1();
}
return s;
}
- 递归创建一颗二叉树(树的数据由数组带入 )
BtNode* CreateTree2(ElemType *&str)
{
/*
int main()
{
char *str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTree2(str);
NiceInOrder(root);
}
*/
BtNode *s=NULL;
if(str !=NULL && *str !=END)
{
s=buynode();
s->data=*str;
s->left=CreateTree2(++str);
s->right=CreateTree2(++str);
}
return s;
}
3. 二叉树的删除(两种办法)
- 删除一颗二叉树(递归删除,先删左右孩子,后释放节点)
void DestroyBTree(BtNode *p)
{
if(p !=NULL)
{
DestroyBTree(p->left);
DestroyBTree(p->right);
FreeNode(p); //释放一个节点
}
}
- 删除一颗二叉树(递归删除,先删除根节点,后释放左右孩子,此时需要先标记左右孩子)
void DestroyBTree1(BtNode *p)
{
if(p!=NULL)
{
BtNode *lift =p->left;
BtNode *right =p->right;
FreeNode(p);
DestroyBTree1(p->left);
DestroyBTree1(p->right);
}
}
7. 二叉树的求节点个数
- 递归
int GetSize(BtNode *ptr)
{
if(ptr == NULL)
return 0;
else
return GetSize(ptr->leftchild) + GetSize(ptr->rightchild) + 1;
}
- 非递归
// NiceGetSize(BtNode *ptr);
8. 二叉树的求深度
- 递归
int GetDepth(BtNode *ptr)
{
if(NULL == ptr) return 0;
else max(GetDepth(ptr->leftchild),GetDepth(ptr->rightchild)) + 1;
}
- 非递归
// NiceGetDepth(BtNode *ptr);
9. 二叉树的查询
- 根据值查询节点
BtNode * FindValue(BtNode *ptr,ElemType x)
{
if(ptr == NULL || ptr->data == x) return ptr;
else
{
BtNode *p = FindValue(ptr->leftchild,x);
if(NULL == p)
{
p = FindValue(ptr->rightchild,x);
}
return p;
}
}
- 根据节点查询父节点
// BtNode * FindParent(BtNode *ptr,BtNode *cp1,BtNode *cp2);
BtNode * FindParent(BtNode *ptr, BtNode * cp)
{
if(ptr == NULL || cp == NULL || ptr == cp)
return NULL;
else
return Parent(ptr,cp);
}
BtNode * Parent(BtNode *ptr, BtNode *cp)
{
if(ptr == NULL ||
ptr->leftchild == cp || ptr->rightchild == cp)
{
return ptr;
}
else
{
BtNode *p = Parent(ptr->leftchild,cp);
if(NULL == p)
{
p = Parent(ptr->rightchild,cp);
}
return p;
}
}
11. 利用层次遍历,判断是否满二叉树
bool Is_Full_BinaryTree(BtNode *ptr) //(队列)层次遍历判断是否满二叉树
{
bool tag = true;
if(NULL == ptr) return tag;
queue<BtNode *> qu;
int n = 1;
qu.push(ptr);
while(!qu.empty())
{
int i = 0;
for(; i < n && !qu.empty() ;++i)
{
ptr = qu.front(); qu.pop();
if(ptr->leftchild != NULL)
{
qu.push(ptr->leftchild);
}
if(ptr->rightchild != NULL)
{
qu.push(ptr->rightchild);
}
}
if(i < n) { tag = false; break;}
n+=n;
}
return tag;
}
12. 利用队列,判断是否完全二叉树![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/34f188aaee73e157e31ff44cb41d2357.png)
bool Is_Comp_BinaryTree(BtNode *ptr) //完全二叉树
{
bool tag = true;
if(NULL == ptr) return tag;
queue<BtNode *> qu;
qu.push(ptr);
while(!qu.empty())
{
ptr = qu.front(); qu.pop();
if(NULL == ptr) break;
qu.push(ptr->leftchild);
qu.push(ptr->rightchild);
}
while(!qu.empty())
{
ptr = qu.front(); qu.pop();
if(NULL != ptr)
{
tag = false;
break;
}
}
return tag;
}