双亲表示(数组表示)的树的基本操作

 

用数组表示的双亲节点树的基本操作更新版:树的遍历,树的深度,叶子结点的计算,树的构建

#include<iostream>

#include<stdio.h>
#include<cstdio>
#include <malloc.h>
#include<string>
#include<cstring>
#include<queue>
using namespace std;
#define MAX_TREE_SIZE 100
typedef struct {
    char data;
    int parent;
}PTNode;
typedef struct{
    PTNode node[100];
    int count;
}PTree;


/**
二叉树
        1
       / \
      2   3
       \   \
        4   5
       /
      6
a[10]={1,2,3,0,4,0,5,0,0,6,0};
**/
/**
双亲表示法
              R
            / | \
           A  B  C
          / \    |
         D   E   F
                /|\
               G H K


        0 R -1
        1 A 0
        2 B 0  *
        3 C 0
        4 D 1  *
        5 E 1  *
        6 F 3
        7 G 6  *
        8 H 6  *
        9 K 6  *
        标*的为叶子节点
*/
/*
void CreateTree(PTree *T)
{
    LinkQueue q;
    int p,qq;
    int i=1,j,l;
    char c[MAX_TREE_SIZE];
    InitQueue(&q);
    cin>>T->node[0].data;
    if(T->node[0].data!=NULL)
    {
        T->node[0].parent=-1;///根节点
        qq.name=T->node[0].data;
        qq.num=0;
        EnQueue(&q,qq);




    }
}
*/
void init_ptree(PTree &tree)
{
    tree.count=-1;
    //节点记录从0开始的数组
}
void add_ptnode(PTree &tree,PTNode ptnode)
{
    tree.count++;
    tree.node[tree.count].data=ptnode.data;
    tree.node[tree.count].parent=ptnode.parent;
}
void print(PTree &tree)
{
    int i;
    for(i=0;i<=tree.count;i++)
    {
        cout<<"  "<<i<<"  "<<tree.node[i].data<<"   "<<tree.node[i].parent<<endl;


    }
}
int maxnum=0;
/*
int Shen(PTree &tree ,int num,int i)
{


    if(tree.node[num].parent>=0){
        max[i]=max[i]+1;
        return Shen(tree,tree.node[num].parent,i);
    }


}
*/
void  pre(PTree &tree, int num)
//前序遍历
{
    //maxnum=0;
    for(int i=num;i<=tree.count;i++)
    {
        if(i==num)
        {
           //maxnum++;
            cout<<"   "<<i<<"   "<<tree.node[i].data<<"   "<<tree.node[i].parent<<endl;
            for(int j=num+1;j<=tree.count;j++)
            {
                if(tree.node[j].parent==i)
                {
                    pre(tree,j);
                }
            }
        }
    }
}
int nn=0;
int treedepth(PTree &tree,int n){
    int temp=tree.node[n].parent;
    nn++;
    if(temp==-1)
    {
        return nn;
    }
    else {
        return treedepth(tree, temp);
    }
}
//后序遍历
void Back(PTree &tree,int num)
{
    for(int i=num;i<=tree.count;i++)
    {
        if(i==num)
        {
            for(int j=num+1;j<=tree.count;j++)
            {
                if(tree.node[j].parent==i)
                {
                    Back(tree,j);
                    //break;
                }
            }
            cout<<"  "<<i<<"  "<<tree.node[i].data<<"  "<<tree.node[i].parent<<endl;


        }
    }
}
int Findnode(PTree &tree)
{


    int num[100]={0};
    int cot=0;
    int b;
    for(int i=0;i<=tree.count;i++)
    {
        b=tree.node[i].parent;
        if(b>=0){
        num[b]=1;
        }
    }


    for(int j=0;j<=tree.count;j++)
    {
        if(!num[j]){
            cot++;
        }
    }
    return cot;
}
int FindNode(PTree &tree)
{
    int num[100];
    int cot=0;
    memset(num,0,sizeof(num)/sizeof(int));
    for(int i=0;i<=tree.count;i++)
    {


        int b=tree.node[i].parent;
        //根节点的父亲是-1,num用来记录有儿子的节点,没有儿子的节点则为叶子节点
        if(b>=0)
        {
            num[b]=1;
        }
    }
    for(int j=0;j<=tree.count;j++)
    {
        if(!num[j])
        cot++;
    }
    return cot;
}
/*
int TreeDepth(PTree *T)
{
    int k,m,def,max=0;
    for(k=0;k<T->n;++k)
    {
        def=1;
        m=T->node[k].parent;
        while(m!=-1)
        {
            m=T->node[m].parent;
            def++;
        }
        if(max<def)
            max=def;
    }
    return max;
}*/
int main(){
    PTree ptree;
    init_ptree(ptree);
    PTNode ptnode;
    while(cin>>ptnode.data>>ptnode.parent){
        if(ptnode.data=='#')
            break;
        add_ptnode(ptree,ptnode);
    }
    cout<<"结点数目"<<endl;
    cout<<ptree.count+1<<endl;
    //数组从0开始,要加一
    cout<<"按数组顺序遍历"<<endl;
    print(ptree);
    cout<<"先序遍历"<<endl;
    //cout<<pre(ptree,0)<<endl;
    pre(ptree,0);
    cout<<"后序遍历"<<endl;
    Back(ptree,0);
    int cot=Findnode(ptree);
    cout<<"叶子节点数"<<endl;
    cout<<cot<<endl;
    int p=ptree.count-1;
    int depmax=-1;
    for(int k=p;k>ptree.node[p].parent;k--){
        int numb=treedepth(ptree,k);
        depmax=max(depmax,numb);
        nn=0;
    }
    cout<<"递归法查找树的深度"<<endl;
    cout<<depmax<<endl;
    int maxdeep=0,te=0;
    for(int l=0;l<ptree.count;l++)
    {
        te=0;
        for(int o=l;o!=-1;o=ptree.node[o].parent)
        {
            te++;
        }
        maxdeep=max(maxdeep,te);
    }
    cout<<"for循环查找树的深度"<<endl;
    cout<<maxdeep<<endl;




    //CreateTree(T);
}
/***
测试样例,输入##停止


 R -1
 A 0
 B 0
 C 0
 D 1
 E 1
 F 3
 G 6
 H 6
 K 6


 ##
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值