二叉树的相关递归操作
node* createTree(char a)
{
if(a!='#')
{
node* root=new node;
root->a=a;
char b;
cin>>b;
root->lchild=createTree(b);
cin>>b;
root->rchild=createTree(b);
return root;
}
else
return NULL;
}
void preOrder(node* p)
{
//函数的作用:对p进行判断如果p存储数据,则输出,然后对p的左右子节点进行相同的判断。
if(p)
{
cout<<p->a<<endl;
preOrder(p->lchild);
preOrder(p->rchild);
}
}
int leafCount(node* p)
{
//函数作用:输出p节点构成的数的叶节点数量
if(!p)
return 0;
else if(!p->lchild && !p->rchild)
return 1;
else
return leafCount(p->lchild)+leafCount(p->rchild);
}
int treeDepth(node* p)
{
if(!p)
return -1;
return 1+max(treeDepth(p->lchild),treeDepth(p->rchild));
}
node* copyTree(node* p)
{
if(!p)return NULL;
node* root=new node;
root->a=p->a;
root->lchild=copyTree(p->lchild);
root->rchild=copyTree(p->rchild);
return root;
}
堆相关操作:堆用数组存储同时根节点的数组下标为0.则i节点的左右子树的位置为2*i+1和2*i+2.
1.调整一颗左右子树满足堆性质,只有根节点需要重新构造堆的子树
//对i节点为根节点,且其左右子树以满足堆的树进构造,使得i及其子节点构成堆。n是堆的最后节点的位置(最后一位数据的数组下标)
void adjustInode(int* a, int i, int n)
{
while(i<=(n-1)/2)//在此条件下,i是一定会有子节点的、下面分别判断:
{
if(2*i+2<=n)//i的左右节点都存在
{
int j=a[i*2+1]> a[i*2+2]? (i*2+1):(i*2+2);
if(a[j] > a[i])
{
swap(a[j],a[i]);
i=j;
}
else break;
}
else//i只存在左节点
{
if(a[i]<a[2*i+1])
{
swap(a[i],a[2*i+1]);
i=2*i+1;
}
else break;
}
}
}
2.堆的插入
//1)堆的末位置+1,
//2)堆末位赋值新增的数
//3)游标i指向新增数位置,不断跟父亲比较,直到不需要交换
void pushHeap(int* a,int b,int& n)
{
n++;
a[n]=b;
int i=n;
while(i>1)
{
if(a[i]>a[(i-1)/2])
{
swap(a[i],a[(i-1)/2]);
i=(i-1)/2;
}
else
break;
}
}
3.堆的删除
//1,将根节点数据用最后一位节点数据替代
//2,调整首节点为根的树,使其成为堆(左右子树已经满足堆性质)
void popHeap(int* a, int& n)
{
a[0]=a[n];
adjustInode(a,0,n-1);//
}
4.堆的创建
//将游标i从最后一颗子树开始(位置为(n-1)/2),不断前移直到堆的根(i=0),对树进行堆构造。
//能构造成功的原因是:i是从后向前移动的,其移动到某位置后,其左右子树必然已经构成了堆。
void createHeap(int* a,int& n)
{
int j=(n-1)/2;
for(int i=j;i>=0;i--)
adjustInode(a,i,n);
}