2 qq 22210253 qq_22210253 于 2016.02.04 17:55 提问

windows编程 树的画图问题

我的B-树是使用链表作为存储结构的,在绘制B-树的图像的时候,如何确定结点在画布上的位置?我想的是利用树的遍历操作,每遍历一个结点就画出这个结点的图像,但是这个结点的位置怎么确定?图片说明
今天想了好久,希望大神帮忙看一下,谢谢!

5个回答

qq_28410301
qq_28410301   2016.02.06 14:58
已采纳

http://download.csdn.net/detail/qq_28410301/9275927

看这个 全写里面了。
我可以给你大概讲讲,首先你向右边遍历,在遍历的函数中添加一个额外的int类型的参数a,当你在遍历的过程中,一直让这个数值a=a+3,加多少你自己订就好,不多说了,直接看代码,不会的看上面的链接,里面有详细的说明文档和想法。

#include
#include "binaryTreeNode.h"
#include
#include
#include
using namespace std;

bool isOperator (char a)//判断是否为操作符
{
if(a=='+'||a=='-'||a=='*'||a=='/'||a=='('||a==')')
return true;
return false;
}

string inToPost (string s)//中序转后序
{
char temp;
string post="";
stack h;//运算符进栈

for(int i=0;i<s.size();i++)
{
    temp=s[i];
    //cout<<"S[i] :"<<s[i]<<endl;

    if(isOperator(temp))   //是操作符 分两种情况 h为空和不空
    {
        //cout<<"ff"<<endl;
        if(h.empty()) //h为空
        {
            //cout<<"kk"<<endl;
            h.push(temp);
            continue;
        }
        else     //h不为空
        {
            if(temp=='(')
            {
                h.push(temp);
                continue;
            }
            if(temp==')')
            {
                while((!h.empty()) && h.top()!='(' )
                {
                    post+=h.top();
                    h.pop();
                }
                h.pop();
                continue;               
            }
            if(temp=='+'||temp=='-')
            {
                //cout<<"Operator :"<<temp<<endl;
                //cout<<"tt"<<endl;
                while((!h.empty()) && h.top()!='(' )
                {
                    //cout<<h.top()<<endl;
                    post+=h.top();
                    //cout<<post<<endl;
                    h.pop();
                    //bool r=h.empty();
                    //cout<<r<<endl;
                    //cout<<"pp"<<endl;
                }
                h.push(temp);
                continue;
            }
            if(temp=='*'||temp=='/')
            {
                while((h.top()=='*' || h.top()=='/') && (!h.empty()) )
                {
                    post+=h.top();
                    h.pop();
                }
                h.push(temp);
                continue;
            }
        }
    }
    else//不是操作符 是数字
        post+=s[i];

}

for(;!h.empty();)
{
    post+=h.top();
    h.pop();
}

return post;

}

void postToBinary (binaryTreeNode* &tree,string s)//后序转二叉树
{
char temp;
int i=0;
temp=s[i];

stack<binaryTreeNode*> k;//存几个有用的节点 (就是还没有相关联的节点)

while(temp!='\0')//当s没有扫到右边尾部时
{
    tree = new binaryTreeNode(temp);

    if(!isOperator(temp))//直接是数字 不是字符的情况
    {
        k.push(tree);
        temp=s[i++];
    }
    else//为字符的情况
    {
        if(!k.empty())
        {
            tree->rightChild=k.top();
            k.pop();
        }
        if(!k.empty())
        {
            tree->leftChild=k.top();
            k.pop();
        }
        k.push(tree);
        temp=s[i++];
    }
}

}

//ofstream ofs("target.txt", ios::out);

ofstream out ("a.txt",ios::out);

void outPutTree (binaryTreeNode* tree,int theDistance)
{
if(tree)//树不为空
{
outPutTree (tree->rightChild, theDistance+3);
for(int i=0; i out cout coutelement < outelement < for(int j=0;j out cout outPutTree (tree->leftChild , theDistance+3);
}
}

void freeTree(binaryTreeNode* & tree)//释放树
{
if(tree->leftChild!=NULL)
freeTree(tree->leftChild);
if(tree->rightChild!=NULL)
freeTree(tree->rightChild);
delete(tree);
}

void main ()
{
string s;
cin>>s;
binaryTreeNode* tree;

s=inToPost(s);

postToBinary(tree,s);

outPutTree(tree,0);

freeTree(tree);
system("pause");

}


qq_22210253
qq_22210253 谢谢这么详细的回答!你说的很对,变着法的遍历就行了,一次遍历解决不了任何问题
接近 2 年之前 回复
devmiao
devmiao   Ds   Rxr 2016.02.04 21:44

位置可以先排列好最后一排,再算出上一层,以此类推!

xyz347
xyz347   2016.02.04 18:53

先获取树的深度n,那么叶子节点最多有2^n个,假设每个节点画出来的框框大小为1,那么需要的长度就是2^n。根节点y坐标是0,x是2^(n-1),每往下一层y加1,左孩子是左边的一半,右孩子是右边的一半,依次类推

qq_22210253
qq_22210253 不好意思我一开始上传的图片不好,不是二叉树
接近 2 年之前 回复
paopaoTT
paopaoTT   2016.02.04 19:13

左小右大,有就加就可

qq_28410301
qq_28410301   2016.02.06 15:01

上面的 你有不会的再问吧 二叉树的问题挺有趣的 只要变着方法遍历就可以了 楼主觉得可以望采纳.....

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!