树林与二叉树的转换(仅代码)

#ifndef FORESTANDBTREE_H
#define FORESTANDBTREE_H
#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;

//int转string
void AppendInt(string &s,int &a){
    char buf[10];
    itoa(a,buf,10);
    s+=buf;
}

//dot语言声明二叉树结点
string BNodeInfo(int e){
    string father="";
    string element="";
    AppendInt(element,e);
    father+=element;
    father+="[label=\"<f0>|<f1>";
    father+=element;
    father+="|<f2>\"]";
    return father;
}

//二叉树结点
struct binaryTreeNode
{
    //所存储元素
    int element;
    //左孩子、右孩子
    binaryTreeNode *leftChild,
                     *rightChild;
    //构造函数
    binaryTreeNode() {leftChild = rightChild = NULL;}
    binaryTreeNode(int& theElement):element(theElement)
    {
        leftChild = rightChild = NULL;
    }
    binaryTreeNode(int& theElement,
                  binaryTreeNode *theLeftChild,
                  binaryTreeNode *theRightChild)
                  :element(theElement)
    {
        leftChild = theLeftChild;
        rightChild = theRightChild;
    }
};

//森林结点
struct ForestNode
{
    //所存储元素
    int element;
    //指向孩子或兄弟的指针
    ForestNode *next;
    //构造函数
    ForestNode() {element=0;next=NULL;}
    ForestNode(int& theElement):element(theElement)
    {
        next=NULL;
    }
    ForestNode(int& theElement,ForestNode *thenext)
                  :element(theElement)
    {
        next=thenext;
    }
};

//链表类
class chain
{
    public:
        friend class Forest;
        //构造函数
        chain(){firstnode=NULL;csize=0;}
        //析构函数
        ~chain();
        //返回链表元素个数
        int size(){return csize;}
        //插入操作
        void insert(int key);
        //删除操作
        bool erase(int key);
    private:
        ForestNode* firstnode;//头节点
        int csize;//链表元素个数
};

//析构函数
chain::~chain()
{
    while(firstnode!=NULL)
    {
        ForestNode *p=firstnode->next;
        delete firstnode;
        firstnode=p;
    }
}
//插入操作
void chain::insert(int key)
{
    ForestNode *p=firstnode;
    ForestNode *q=NULL;
    //查找插入的位置
    //移动指针q,使得新元素可以插在q的后面
    while(p!=NULL&&p->element<key)
    {
        q=p;
        p=p->next;
    }
    //链表中存在所要插入的元素
    if(p!=NULL&&p->element==key){}
    //找到插入位置则在q之后插入新节点
    else
    {
        ForestNode *t=new ForestNode(key,p);
        //插入位置为头节点
        if(q==NULL)
            firstnode=t;
        //插入位置不在头节点
        else
            q->next=t;
        csize++;
    }
}
//删除操作
bool chain::erase(int key)
{
    ForestNode *p=firstnode;
    ForestNode *q=NULL;
    //搜索数据域为key的节点
    while(p!=NULL&&p->element<key)
    {
        q=p;
        p=p->next;
    }
    //找到匹配的节点
    if(p!=NULL&&p->element==key)
    {
        //删除头节点
        if(q==NULL)
            firstnode=p->next;
        //删除头节点之后的节点
        else
            q->next=p->next;
        delete p;
        csize--;
        return true;
    }
    //未找到要删除节点
    else{return false;}
}
class linkedBinaryTree;
//森林类
class Forest
{
    public:
        friend class linkedBinaryTree;
        //构造函数
        Forest(int n);
        Forest(){NodeSize=0;tree=new chain[5500];}
        //析构函数
        ~Forest(){}
        //初始化
        void Initialize(int m,int n);
        //插入结点
        void InsertNode(int father,int node);
        //插入边
        int InsertEdge(int a,int b);
        //删除结点
        bool EraseNode(int father,int node);
        //森林转二叉树
        binaryTreeNode* ForestToBinaryTree(int root);
        void Transform(linkedBinaryTree& change1);
        //显示森林(遍历森林元素)
        void ShowForest();
        int ShowLevel(int root);
        //森林可视化
        void Visualition();
    protected:
        //孩子链表
        chain *tree;
        //根节点
        vector<int> root;
        //森林结点个数
        int NodeSize;
};

class linkedBinaryTree
{
    public:
        friend class Forest;
        //构造函数
        linkedBinaryTree() {root = NULL;}
        ~linkedBinaryTree(){erase(root);root = NULL;};
        //判断是否为空
        bool empty() const {return root == NULL;}
        //前序遍历
        int preOrder(binaryTreeNode *t);
        //删除结点
        void erase(binaryTreeNode *t);
        //插入结点
        void InsertNode(int pos,int father,int node);
        //初始化
        void Initialize(int n);
        //查找指定元素所对应的位置
        binaryTreeNode* find(int element);
        //前序遍历
        int PreOrder(){return preOrder(root);}
        //层次遍历
        void levelorder(binaryTreeNode *t);
        void LevelOrder(){levelorder(root);cout<<endl;}
        //改变根结点
        void ChangeRoot(binaryTreeNode *t){erase(root);root=t;};
        //二叉树转森林
        void BiNodeToFNode(binaryTreeNode *t,Forest &f);
        void BTreeToForest(Forest &t);
        //二叉树可视化
        void Visualition();
    protected:
        //根结点
        binaryTreeNode *root;
};

void linkedBinaryTree::Visualition(){
    //重定向输出流到dot文件
    freopen("binarytree.dot","w",stdout);
    //dot语言作图
    cout<<"digraph G{"<<endl;
    cout<<"label=\"Binary Tree\";"<<endl;
    cout<<"node[shape=record];"<<endl;
    queue<binaryTreeNode *> q;
    binaryTreeNode *tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode *t=q.front();
        q.pop();
        string father=BNodeInfo(t->element);
        cout<<father<<";"<<endl;
        if(t->leftChild!=NULL){
            string left=BNodeInfo(t->leftChild->element);
            cout<<left<<";"<<endl;
            cout<<t->element<<":f0:sw->"<<t->leftChild->element<<":f1;"<<endl;
            q.push(t->leftChild);
        }
        if(t->rightChild!=NULL){
            string right=BNodeInfo(t->rightChild->element);
            cout<<right<<";"<<endl;
            cout<<t->element<<":f2:se->"<<t->rightChild->element<<":f1;"<<endl;
            q.push(t->rightChild);
        }
    }
    cout<<"}"<<endl;
    fclose(stdout);
    //命令行输出图片
    string s = "";
    s += "dot -Tpng ";
    s += "binarytree.dot";
    s += " -o ";
    s+="binarytree.png";
    const char* cmd = s.data();
    system(cmd);
    //重新开启屏幕输出流
    freopen("CON","w",stdout);
}
//二叉树层次遍历
void linkedBinaryTree::levelorder(binaryTreeNode *t){
    queue<binaryTreeNode *> q;
    q.push(t);
    while(!q.empty()){
        binaryTreeNode *p=q.front();
        cout<<p->element<<" ";
        q.pop();
        //扩展左子树
        if(p->leftChild!=NULL)
            q.push(p->leftChild);
        //扩展右子树
        if(p->rightChild!=NULL)
            q.push(p->rightChild);
    }
}
//查找指定元素所在的位置
binaryTreeNode* linkedBinaryTree::find(int element){
    queue<binaryTreeNode*> q;
    binaryTreeNode* tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode* t=q.front();
        q.pop();
        if(t->element==element)
            return t;
        //查找左子树
        if(t->leftChild!=NULL)
            q.push(t->leftChild);
        //查找右子树
        if(t->rightChild!=NULL)
            q.push(t->rightChild);
    }
    return NULL;
}
//二叉树初始化
void linkedBinaryTree::Initialize(int n){
    //指定根节点
    int rr;
    cin>>rr;
    binaryTreeNode* nodes[n+10];
    for(int i=1;i<=n;i++){
        nodes[i]=new binaryTreeNode(i);
    }
    int A,l,r;
    //输入结点信息并插入
    for(int i=0;i<n;i++){
        cin>>A>>l>>r;
        //插入左孩子
        if(l!=-1)
            nodes[A]->leftChild=nodes[l];
        //插入右孩子
        if(r!=-1)
            nodes[A]->rightChild=nodes[r];
    }
    root=nodes[rr];
}
//插入结点
void linkedBinaryTree::InsertNode(int pos,int father,int node){
    queue<binaryTreeNode*> q;
    binaryTreeNode* tmp=root;
    q.push(tmp);
    while(!q.empty()){
        binaryTreeNode* t=q.front();
        q.pop();
        //找到对应的位置
        if(t->element==father){
            //插入右孩子
            if(pos==0){
                t->rightChild=new binaryTreeNode(node);
            }
            //插入左孩子
            else{
                t->leftChild=new binaryTreeNode(node);
            }
            return;
        }
        //扩展查找子树
        if(t->leftChild!=NULL)
            q.push(t->leftChild);
        if(t->rightChild!=NULL)
            q.push(t->rightChild);
    }
}
//删除结点
void linkedBinaryTree::erase(binaryTreeNode *t)
{
    if (t != NULL)
    {
        //删除左子树
        erase(t->leftChild);
        //删除右子树
        erase(t->rightChild);
        //释放结点空间
        delete t;
    }
}
//前序遍历
int linkedBinaryTree::preOrder(binaryTreeNode *t)
{
    int sum=0;
    if (t != NULL)
    {
        //访问父结点
        sum^=t->element;
        //前序遍历左子树
        sum^=preOrder(t->leftChild);
        //前序遍历右子树
        sum^=preOrder(t->rightChild);
    }
    return sum;
}
//二叉树转树
void linkedBinaryTree::BiNodeToFNode(binaryTreeNode *t,Forest &f)
{
    binaryTreeNode* r=t;
    binaryTreeNode* p=r;
    //沿左孩子方向进行转换
    while(r!=NULL){
        int father=r->element;
        p=r->leftChild;
        while(p!=NULL){
            f.tree[father].insert(p->element);
            p=p->rightChild;
            //递归转换右子树
            BiNodeToFNode(p,f);
        }
        r=r->leftChild;
    }
}
//二叉树转森林
void linkedBinaryTree::BTreeToForest(Forest &t)
{
    vector<binaryTreeNode*> ROOT;
    binaryTreeNode *tmp=root;
    //分离根结点
    while(tmp!=NULL){
        binaryTreeNode *rroot=new binaryTreeNode(tmp->element);
        rroot->leftChild=tmp->leftChild;
        ROOT.push_back(rroot);
        tmp=tmp->rightChild;
    }
    int size=ROOT.size();
    //对分离后的根结点执行转换操作
    for(int i=0;i<size;i++){
        t.root.push_back(ROOT[i]->element);
        binaryTreeNode* r=ROOT[i];
        BiNodeToFNode(r,t);
    }
}

void Forest::Visualition(){
    //重定向输出流到dot文件
    freopen("forest.dot","w",stdout);
    //dot语言作图
    cout<<"digraph G{"<<endl;
    cout<<"label=\"Forest\";"<<endl;
    cout<<"node[shape=circle];"<<endl;
    sort(root.begin(),root.end());
    int size=root.size();
    for(int i=0;i<size;i++){
        queue<int> q;
        q.push(root[i]);
        cout<<root[i]<<";"<<endl;
        while(!q.empty()){
            int tmp=q.front();
            q.pop();
            ForestNode *p=tree[tmp].firstnode;
            while(p!=NULL){
                cout<<p->element<<";"<<endl;
                cout<<tmp<<"->"<<p->element<<";"<<endl;
                q.push(p->element);
                p=p->next;
            }
        }
    }
    cout<<"}"<<endl;
    fclose(stdout);
    //命令行输出图片
    string s = "";
    s += "dot -Tpng ";
    s += "forest.dot";
    s += " -o ";
    s+="forest.png";
    const char* cmd = s.data();
    system(cmd);
    //重新开启屏幕输出流
    freopen("CON","w",stdout);
}
//构造函数
Forest::Forest(int n){
    NodeSize=n;
    tree=new chain[n+200];
}
//森林初始化
void Forest::Initialize(int m,int n){
    int NodeElement;
    //输入根结点
    for(int i=1;i<=m;i++){
        int rootnode;
        cin>>rootnode;
        root.push_back(rootnode);
    }
    int father,num;
    //根据输入信息插入结点
    for(int i=1;i<=n;i++){
        cin>>father>>num;
        while(num--){
            cin>>NodeElement;
            tree[father].insert(NodeElement);
        }
    }
}
//层次遍历树
int Forest::ShowLevel(int root){
    int sum=0;
    queue<int> q;
    q.push(root);
    sum^=root;
    while(!q.empty()){
        int tmp=q.front();
        q.pop();
        ForestNode *p=tree[tmp].firstnode;
        //按层扩展
        while(p!=NULL){
            sum^=p->element;
            q.push(p->element);
            p=p->next;
        }
    }
    return sum;
}
//层次遍历森林
void Forest::ShowForest(){
    //对根结点从小到大排序
    sort(root.begin(),root.end());
    int size=root.size();
    //遍历森林中的每一颗树
    for(int i=0;i<size;i++)
        cout<<ShowLevel(root[i])<<" ";
    cout<<endl;
}
//插入结点
void Forest::InsertNode(int father,int node){
    //插入根节点
    if(father==-1){
        root.push_back(node);
    }
    //插入子结点
    else{
        tree[father].insert(node);
    }
    NodeSize++;
}
//删除结点
bool Forest::EraseNode(int father,int node){
    bool flag=false;
    //删除根结点
    if(father==-1){
        vector<int>::iterator iter=root.begin();
        while(iter!=root.end()){
            if(*iter==node){
                flag=true;
                root.erase(iter);
                break;
            }
            iter++;
        }
        ForestNode *p=tree[node].firstnode;
        while(p!=NULL){
            root.push_back(p->element);
            ForestNode *q=p->next;
            delete p;
            p=q;
        }
    }
    //删除的不是根结点
    else{
        flag=tree[father].erase(node);
        ForestNode *p=tree[node].firstnode;
        while(p!=NULL){
            root.push_back(p->element);
            ForestNode *q=p->next;
            delete p;
            p=q;
        }
    }
    NodeSize--;
    return flag;
}
//插入边
int Forest::InsertEdge(int a,int b){
    bool flaga=0;
    bool flagb=0;
    vector<int>::iterator iter=root.begin();
    //首先判断输入的a、b是否为根结点并将b从根结点数组中删除
    while(iter!=root.end()){
        if(*iter==a){
            flaga=true;
        }
        if(*iter==b){
            flagb=true;
            root.erase(iter);
        }
        iter++;
    }
    //a、b连接
    if(flaga&&flagb){
        tree[a].insert(b);
        return 0;
    }
    else if(flaga&&!flagb){
        return 2;
    }
    else if(!flaga&&flagb){
        return 1;
    }
    else
        return 3;
}
//树转二叉树
binaryTreeNode* Forest::ForestToBinaryTree(int root)
{
    binaryTreeNode* binaryRoot = new binaryTreeNode(root);
    if (tree[root].size()<=0){
        return binaryRoot;
    }
    //递归转换左子树
    binaryRoot->leftChild = ForestToBinaryTree(tree[root].firstnode->element);
    //兄弟结点变右子树
    binaryTreeNode *brotherChild = binaryRoot->leftChild;
    ForestNode *p=tree[root].firstnode->next;
    while(p!=NULL)
    {
        brotherChild->rightChild = ForestToBinaryTree(p->element);
        brotherChild = brotherChild->rightChild;
        p=p->next;
    }
    return binaryRoot;
}
//森林转二叉树
void Forest::Transform(linkedBinaryTree& change1){
    //对根结点进行排序
    sort(root.begin(),root.end());
    binaryTreeNode *t=ForestToBinaryTree(root[0]);
    binaryTreeNode* tmp=t;
    int size=root.size();
    //对森林中的每颗树进行转换并连接
    for(int i=1;i<size;i++){
        tmp->rightChild=ForestToBinaryTree(root[i]);
        tmp=tmp->rightChild;
    }
    change1.ChangeRoot(t);
}

#endif // FORESTANDBTREE_H

原文章,点击前往

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值