DS:二叉树链表操作

深刻地提出一个问题:
为什么上机课死活写不出来,课下只需一小时…
黑人问号😳😳😳😳,似乎还有期中上机??

现总结一下这周的二叉树叭~
课上连个层次创建都写不出来,真的不知道为啥
& 这周都在弄二叉树的链表操作


各层平均值

给定一个非空的二叉树,节点值为整型,设计程序计算该二叉树每层的节点值的平均值, 将各层均值放入一个序列输出
输入
5 7 15 3 -1 -1 20
输出
5 11 11.5

#include<iostream>
#include<queue>
using namespace std;
int a[100]={0},n=0;
template <typename T>
class BinTreeNode
{
public:
    BinTreeNode(){lchild=NULL;rchild=NULL;}
    T data;
    BinTreeNode *lchild, *rchild;
    BinTreeNode(const T&t):data(t),lchild(NULL),rchild(NULL){}
};
template <typename T>
class BinTree
{
public:
   BinTree(){root->lchild=NULL;root->rchild=NULL;}
    BinTreeNode<T> *root;
    void create(BinTreeNode<T> *root,int i);
    void print_layer_mean_value();
    void show(BinTreeNode<T> *root);
};

template<typename T>
void BinTree<T>::create(BinTreeNode<T> *root,int i)
{  if(i>=n) return;
    if(a[i]==-1) return;
root->data=a[i];
if(2*i+1<n){
    root->lchild=new BinTreeNode<T>;
    root->lchild->lchild=NULL;
    create(root->lchild,2*i+1);}
if(2*i+2<n){
    root->rchild=new BinTreeNode<T>;
    root->rchild->lchild=NULL;
    root->rchild->rchild=NULL;
    create(root->rchild,2*i+2);}
   
}
    
template<typename T>
void BinTree<T>::show(BinTreeNode<T> *root)
{  queue<BinTreeNode<T> *> Q;
Q.push(root);
while(!Q.empty()){
    BinTreeNode<T> *p=Q.front();
    Q.pop();
    if(p->data!=0) cout<<p->data<<" ";
    if(p->lchild!=NULL)
        Q.push(p->lchild);
    if(p->rchild!=NULL)
        Q.push(p->rchild);
}
}

template<typename T>
void BinTree<T>::print_layer_mean_value()
{   int j=0,t=0,v=0;
    int num[100]={0};
    for(int i=1,temp=0;temp<=n;temp+=i,i*=2,j++)
        num[j]=i;
    for(int i=0,k=0;i<=j&&k<n;i++)
    {   t=0;v=num[i];
        for(int p=0;p<num[i];p++,k++)
        {
            if(a[k]==-1||a[k]==0) v--;
            else t+=a[k];
        }
        float av=t*1.0/v;
            cout<<av<<" ";}
    
    }
    
int main()
{
    BinTree<int> tree;
    cout<<"input n:"<<endl;
    cin>>n;
    cout<<"input "<<n<<" numbers:"<<endl;
    for(int i=0;i<n;i++)
        cin>>a[i];
    tree.create(tree.root,0);
    cout<<"tree:"<<endl;
    tree.show(tree.root);cout<<endl;
    cout<<"average:"<<endl;
    tree.print_layer_mean_value();cout<<endl;
}

emm开始卡在创建,但现在康康不是很难
要注意引入下标i来指示层次创建,因为用了数组储存,所以可以判断一个结点的子女节点的位置,利用这一点创建
哦对我竟然还卡层次遍历…用队列!!
最后那个算平均值在课上搞了好久,还是对数组操作,本来想研究直接遍历二叉树但未果…数组操作就要注意判断一层非空节点的个数


展开二叉树为链表

将二叉树展开成链表(按照二叉树的前序遍历), 节点值为整形,左结点为NULL,右结点为下一结点
有趣的操作啊
输入
1 2 5 3 4 -1 6
输出
1 2 3 4 5 6
在这里插入图片描述

template<typename T>
void recursive_f(BinTreeNode<T> *root)
{
    if(root==NULL) return;
    if(root->lchild!=NULL)
    {
        if(root->rchild==NULL)
        {root->rchild=root->lchild;
        root->lchild=NULL;}
    else
    {
        BinTreeNode<T> *p=root->rchild,*q=root->lchild;
        root->rchild=root->lchild;
        root->lchild=NULL;
        while(q->rchild!=NULL)
            q=q->rchild;
        q->rchild=p;
    }//每次都把右孩子接到左孩子的最右下结点之后,把左孩子放到右孩子节点
        recursive_f(root->rchild);
    }}

template<typename T>
void nonrecursive_f(BinTreeNode<T> *root)
{
    if(root==NULL) return;
    while(root!=NULL)
    {
        if(root->lchild!=NULL)
    {
        if(root->rchild==NULL)
        {root->rchild=root->lchild;
        root->lchild=NULL;}
    else
    {
        BinTreeNode<T> *p=root->rchild,*q=root->lchild;
        root->rchild=root->lchild;
        root->lchild=NULL;
        while(q->rchild!=NULL)
            q=q->rchild;
        q->rchild=p;}
    }
            root=root->rchild;
    }
}

int main(){
    BinTree<int> tree;
    cout<<"input n:"<<endl;
    cin>>n;
    cout<<"input "<<n<<" numbers:"<<endl;
    for(int i=0;i<n;i++)
        cin>>a[i];
    tree.create(tree.root,0);
    cout<<"tree:"<<endl;
    tree.show(tree.root);cout<<endl<<endl;
    cout<<"call recuisive_f:"<<endl;
    nonrecursive_f(tree.root);
    cout<<"list:"<<endl;
    tree.showafter(tree.root);
    cout<<endl<<endl<<"call nonrecuisive_f:"<<endl;
    nonrecursive_f(tree.root);
    cout<<"list:"<<endl;
    tree.showafter(tree.root);cout<<endl;
}

二叉树的类定义和创建同上,略去
这题课上没思路,但回来看看不是很简单嘛…
思路:数次操作,每次都把左节点放到右结点,把原来的右结点移到左节点的最右下结点,如果左有右无,直接把左结点放到右结点即可
实现了递归&非递归

对自己也很无语
两次上机课之后都有点沮丧,觉得自己有些课挺差的
或许是临场发挥的问题吧
或许是限时对我来说有太大的压力
但是还是要加油冲呀!!无论结果如何,一定要尽力
万事都要全力以赴,包括开心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值