二叉搜索树的广度优先遍历(C++实现)

3
也许是个简单的问题。我已经实现了一个二叉树,现在希望将二叉搜索树转换为数组,或者至少像数组一样打印输出。我遇到的问题是如何在其中添加 NULL/flags '\0'。
例如,假设我有这样一棵树:
                10
               /  \
              6   12
             / \   \
            1  8   15
             \
              4   

我希望它能按照应有的打印方式进行打印。例如:
        [10,6,12,1,8,\0,15,\0,4,\0,\0,\0,\0,\0,\0]
        ^Something Like this^ I don't know if I counted the NULL correctly.

另一种显示树型结构的方式是如何正确输出间距,例如用 '/' 和 '\' 指向父节点的键:

                10
               /  \
              6   12
             / \   \
            1  8   15
             \
              4   

这里有一些我试着在代码上详细解释的内容,但是我卡住了:

void BreadthFirstTravseral(struct node* root)
{
    queue<node*> q;

    if (!root) {
        return;
    }
    for (q.push(root); !q.empty(); q.pop()) {
        const node * const temp_node = q.front();
        cout<<temp_node->data << " ";

        if (temp_node->left) {
            q.push(temp_node->left);
        }
        if (temp_node->right) {
            q.push(temp_node->right);
        }
    }
}

任何形式的帮助、链接、建议和示例代码都将不胜感激。
5个回答

6

由于一个键可能有多个数字,这将影响给定节点上面所有级别的间距,因此正确设置间距会非常困难。

至于如何添加NULL - 只需在打印NULL的if语句中添加else子句即可:

if (root) {
  q.push(root);
  cout << root->data << " ";  
} else {
  cout << "NULL ";
}
while (!q.empty()) {
    const node * const temp_node = q.front(); 
    q.pop();

    if (temp_node->left) {
      q.push(temp_node->left);
      cout << temp_node->left->data << " ";
    } else {
      cout << "NULL ";
    }


    if (temp_node->right) {
      q.push(temp_node->right);
      cout << temp_node->right->data << " ";
    } else {
      cout << "NULL ";
    }
}

2
While循环将永远不会停止,因为队列中没有任何元素被弹出。我的计算机系统正在实现无限循环。 - Conor
@Xaphen 是的,谢谢你。我忘记弹出了。我会立即修复。 - Ivaylo Strandjev

3
void TreeBreadthFirst(Node*  treeRoot) 
{  
 Queue *queue  = new Queue();

      if (treeRoot == NULL) return;
       queue->insert(treeRoot); 
       while (!queue->IsEmpty())
          {          
          Node * traverse = queue->dequeue();
         cout<< traverse->data << “ “ ;
          if (traverse->left != NULL) 
            queue->insert( traverse->left); 
          if (traverse->right != NULL) 
            queue->insert(traverse->right); 
           } 
      delete queue;
       } 

1
我用C语言编写了一个程序。这段代码会像一棵树一样显示。
struct node{
    int val;
    struct node *l,*r;
};

typedef struct node node;


int findDepth(node *t){
    if(!t) return 0;
    int l,r;
    l=findDepth(t->l);
    r=findDepth(t->r);

    return l>r?l+1:r+1;
}

void disp(node *t){
    if(!t)
        return;
    int l,r,i=0;
    node *a[100],*p;
    int front=0,rear=-1,d[100],dep,cur,h;
    a[++rear]=t;
    d[rear]=0;
    cur=-1;
    h=findDepth(t);
    printf("\nDepth : %d \n",h-1);

    while(rear>=front){
        dep = d[front];
        p=a[front++];
        if(dep>cur){
            cur=dep;
            printf("\n");
            for(i=0;i<h-cur;i++) printf("\t");
        }
        if(p){
            printf("%d\t\t",p->val);
            a[++rear]=p->l;
            d[rear]=dep+1;
            a[++rear]=p->r;
            d[rear]=dep+1;
        }
        else printf ("-\t\t");

    }
}

1
为代码添加一些解释并编辑您的回答。 - gsamaras

0
void BreadthFirstTravseral(struct node* root)
{
    queue<node*> q;

    if (!root) {
        return;
    }
    for (q.push(root); !q.empty(); q.pop()) {
        const node * const temp_node = q.front();
        if( temp_node->special_blank ){
            cout << "\\0 " ;
            continue;//don't keep pushing blanks
        }else{
            cout<<temp_node->data << " ";
        }
        if (temp_node->left) {
            q.push(temp_node->left);
        }else{
            //push special node blank
        }
        if (temp_node->right) {
            q.push(temp_node->right);
        }else{
            //push special node blank
        }
    }
}

什么是“special_blank”标识符? - Conor
你可以在节点结构中添加一个布尔值。如果不是特殊节点,则为false,否则为true。这样就可以捕获特殊的空白节点并打印空叶节点。 - jeremyvillalobos

0
这样怎么样:
std::vector<node*> list;
list.push_back(root);
int i = 0;
while (i != list.size()) {
  if (list[i] != null) {
    node* n = list[i];
    list.push_back(n->left);
    list.push_back(n->right);
  } 
  i++;
}

没有测试过,但我认为它应该可以工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接