#include <iostream>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
int flag = 0,n=0;
typedef struct n//data为节点数据,lchild和rchild分别为左子树和右子树
{
int data;
struct n* lchild, * rchild;
}Tree, * PTree;//定义
int GetHeight(PTree& T)//二叉树的高度
{
if (!T)
return 0;
return max(GetHeight(T->lchild), GetHeight(T->rchild)) + 1;//左右子树中较大者加一
}
PTree zuoxuan(PTree& T)//对树进行调整,插入右孩子的右子树,左旋
{
PTree a = T->rchild;
T->rchild = a->lchild;
a->lchild = T;
return a;
}
PTree youxuan(PTree& T)//对树进行调整,插入左孩子的左子树,右旋
{
PTree a = T->lchild;
T->lchild = a->rchild;
a->rchild = T;
return a;
}
PTree zuoyou(PTree& T)//对树进行调整,先左旋再右旋
{
PTree a = T;
if (!a->rchild)
{
a = youxuan(a);
return a;
}
a->lchild = zuoxuan(a->lchild);
a = youxuan(a);
return a;
}
PTree youzuo(PTree& T)//对树进行调整,先右旋再左旋
{
PTree a = T;
if (!a->lchild)
{
a = zuoxuan(a);
return a;
}
a->rchild = youxuan(a->rchild);
a = zuoxuan(a);
return a;
}
void ist(int a, PTree& T)//插入数据
{
int i, j;
if (!T)
{
T = new Tree;
T->data = a;
T->lchild = NULL;
T->rchild = NULL;
}
else if (a > T->data)
{
ist(a, T->rchild);
if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//判断是否需要调整
{
if (a > T->rchild->data)
{
T = zuoxuan(T);
}
else
{
T = youzuo(T);
}
}
}
else
{
ist(a, T->lchild);
if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//判断是否需要调整
{
if (a < T->lchild->data)
{
T = youxuan(T);
}
else
{
T = zuoyou(T);
}
}
}
}
void cret(int n, PTree& T)//创建二叉树
{
int a, i;
for (i = 0; i < n; i++)
{
scanf("%d", &a);
ist(a, T);
}
}
void PreOrder(PTree& T)//前序遍历递归算法
{
if (T)
{
printf("%d ", T->data);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
void InOrder1(PTree& T)//中序遍历递归算法
{
if (T)
{
InOrder1(T->lchild);
printf("%d ", T->data);
InOrder1(T->rchild);
}
}
void LastOrder(PTree& T)//后序遍历递归算法
{
if (T)
{
LastOrder(T->lchild);
LastOrder(T->rchild);
printf("%d ", T->data);
}
}
void Traverse(PTree& T)//三种次序遍历
{
PreOrder(T);
printf("\n");
InOrder1(T);
printf("\n");
LastOrder(T);
printf("\n");
}
void srch(int a, PTree& T)//查找关键字
{
if (!T)
{
flag = 0;
return;
}
if (a == T->data)
{
flag = 1;
return;
}
else if (a < T->data)
{
srch(a, T->lchild);
}
else
{
srch(a, T->rchild);
}
}
void ExchangeTree(PTree& T)//交换左右子树 (递归实现)
{
if (!T)
return;
swap(T->lchild, T->rchild);
ExchangeTree(T->lchild);
ExchangeTree(T->rchild);
}
int GetNum(PTree& T)//叶子节点的数量
{
if (!T)
return 0;
if (!T->lchild && !T->rchild)
return 1;
return GetNum(T->lchild) + GetNum(T->rchild);//左右子树的叶子节点
}
void InOrder2(PTree& T)//非递归中序遍历
{
if (!T)
{
return;
}
int i, t;
stack<PTree> s;
PTree p = T;
while (p || !s.empty())
{
while (p)
{
s.push(p);
p = p->lchild;
}
if (!s.empty())
{
p = s.top();
s.pop();
printf("%d ", p->data);
p = p->rchild;
}
}
}
void PreOrder2(PTree& T)//非递归前序遍历
{
if (!T)
{
return;
}
int i, t;
stack<PTree> s;
PTree p = T;
s.push(T);
while (!s.empty())
{
p = s.top();
s.pop();
printf("%d ", p->data);
if (p->rchild != NULL)
{
s.push(p->rchild);
}
if (p->lchild != NULL)
{
s.push(p->lchild);
}
}
}
void LastOrder2(PTree& T)//非递归后序遍历
{
if (!T)
{
return;
}
int i, t;
stack<PTree> s;
PTree p = T,q=NULL;
while (p!=NULL||!s.empty())
{
while (p != NULL)
{
s.push(p);
p = p->lchild;
}
p = s.top();
s.pop();
if (p->rchild == NULL || p->rchild == q)
{
q = p;
printf("%d ", p->data);
p = NULL;
}
else
{
s.push(p);
p = p->rchild;
}
}
}
void Traverse2(PTree& T)//三种非递归遍历
{
PreOrder2(T);
printf("\n");
InOrder2(T);
printf("\n");
LastOrder2(T);
printf("\n");
}
void Breadother(PTree& T)//层序遍历
{
PTree p = T;
queue<PTree> s;
if (!T)
{
return;
}
s.push(p);
while (!s.empty())
{
p = s.front();
printf("%d ", p->data);
if (p->lchild)
{
s.push(p->lchild);
}
if (p->rchild)
{
s.push(p->rchild);
}
s.pop();
}
}
PTree min(PTree& T)//删除操作辅助函数,找到最小的结点
{
if (T == NULL)
return NULL;
while (T->lchild)
T=T->lchild;
return T;
}
int dele(PTree& T, int a)
{
if (!T)
{
return 0;
}
if (a < T->data)
{
dele(T->lchild, a);//递归找到要删除结点
if (GetHeight(T->rchild) - GetHeight(T->lchild) > 1)//检测并调整树的平衡性
{
if (a < T->rchild->data)
T = youzuo(T);
else
T = zuoxuan(T);
}
}
else if (a > T->data)
{
dele(T->rchild, a);//递归找到要删除结点
if (GetHeight(T->lchild) - GetHeight(T->rchild) > 1)//检测并调整树的平衡性
{
if (a < T->lchild->data)
T = youxuan(T);
else
T = zuoyou(T);
}
}
else if (T->lchild && T->rchild)//待删除结点有左右孩子
{
flag = 1;
PTree p = min(T->rchild);
T->data = p->data;
dele(T->rchild, p->data);
}
else if (T->lchild)//只有一个孩子或者没有孩子
{
flag = 1;
T = T->lchild;
}
else
{
flag = 1;
T = T->rchild;
}
return 1;
}
int main()
{
int a, b, c,d,l,k;
int i = 0,j=0;
PTree T = NULL;//创建一个AVL树
printf("请输入树的结点数:");
scanf("%d", &n);
cret(n, T);
printf("\n三种遍历(递归):\n");
Traverse(T);
printf("\n三种遍历(非递归):\n");
Traverse2(T);
printf("请输入要查找的数据:");
scanf("%d",&a);
srch(a, T);
printf("%d\n", flag);
flag = 0;
printf("请输入要查找的数据:");
scanf("%d", &b);
srch(b, T);
printf("%d\n", flag);
flag = 0;
i = 1;
while (i)
{
printf("请输入要插入的数据:");
scanf("%d", &c);
ist(c, T);
printf("\n三种遍历:\n");
Traverse(T);
printf("如果要退出插入操作,请输入0,如要继续,请输入1:");
scanf("%d", &i);
}
printf("\n非递归中序遍历:\n");
InOrder2(T);
printf("\n");
printf("层序遍历:\n");
Breadother(T);
printf("\n");
printf("\n交换左右子树\n");
ExchangeTree(T);
printf("\n三种遍历:\n");
Traverse(T);
printf("\n交换左右子树\n");
ExchangeTree(T);
printf("\n三种遍历:\n");
Traverse(T);
printf("二叉树的深度:%d\n", GetHeight(T));
printf("二叉树的叶子结点个数:%d\n", GetNum(T));
i = 1;
while (i)
{
printf("\n请输入要删除的数据:\n");
scanf("%d", &d);
flag = 0;
dele(T, d);
if (flag)
{
printf("\n删除成功!");
}
else
{
printf("\n删除失败!\n");
}
printf("\n三种遍历:\n");
Traverse(T);
printf("如果要退出删除操作,请输入0,如要继续,请输入1:");
scanf("%d", &i);
}
return 0;
}