为啥我的代码不能在二叉搜索树中正确执行预排序?

Posted

技术标签:

【中文标题】为啥我的代码不能在二叉搜索树中正确执行预排序?【英文标题】:Why my code won't do preorder form correctly in Binary Search Tree?为什么我的代码不能在二叉搜索树中正确执行预排序? 【发布时间】:2017-03-22 16:18:38 【问题描述】:

我为字符串编辑了二叉搜索树的代码。但是有一个小问题。当我输入像 A B C D E F 这样的简单输入时,我的程序说预购表格是 A B C D E F... 它实际上应该是 A B D E C F

因为,它应该在根处打印单词,然后在左子树中按预序打印单词,然后在 预排序的右子树。

发布订单也应该打印D E B F C A,但它会打印A B C D E F,并且按订单应该打印D B E A F C...但它只是给了我F E D C B A

感谢任何帮助,我不知道出了什么问题。

这里是工作的完整源代码:

#include <iostream>
#include <string>
#include <conio.h>
using namespace std;

class Node 
string word;
Node* left;
Node* right;
public:
Node()  word=-1; left=NULL; right=NULL; ;
void setWord(string aWord)  word = aWord; ;
void setLeft(Node* aLeft)  left = aLeft; ;
void setRight(Node* aRight)  right = aRight; ;
string Word()  return word; ;
Node* Left()  return left; ;
Node* Right()  return right; ;
;

class Tree 
 Node* root;
public:
 Tree();
 ~Tree();
 Node* Root()  return root; ;
 void addNode(string word);
 void inOrder(Node* n);
 void preOrder(Node* n);
 void postOrder(Node* n);
private:
 void addNode(string word, Node* leaf);
 void freeNode(Node* leaf);
;

Tree::Tree() 
 root = NULL;


Tree::~Tree() 
 freeNode(root);


void Tree::freeNode(Node* leaf)

if ( leaf != NULL )

   freeNode(leaf->Left());
   freeNode(leaf->Right());
   delete leaf;



void Tree::addNode(string word) 
 if ( root == NULL ) 
    Node* n = new Node();
    n->setWord(word);
    root = n;
 
 else 
   addNode(word, root);
 
 

void Tree::addNode(string word, Node* leaf) 
if ( word <= leaf->Word() ) 
   if ( leaf->Left() != NULL )
      addNode(word, leaf->Left());
   else 
      Node* n = new Node();
      n->setWord(word);
      leaf->setLeft(n);
   

else 
   if ( leaf->Right() != NULL )
      addNode(word, leaf->Right());
   else 
      Node* n = new Node();
      n->setWord(word);
      leaf->setRight(n);
   



void Tree::inOrder(Node* n) 
if ( n ) 
   inOrder(n->Left());
   cout << n->Word() << " ";
   inOrder(n->Right());



void Tree::preOrder(Node* n) 
if ( n ) 
   cout << n->Word() << " ";
   preOrder(n->Left());
   preOrder(n->Right());




void Tree::postOrder(Node* n) 
if ( n ) 
   postOrder(n->Left());
   postOrder(n->Right());
   cout << n->Word() << " ";



int main() 
string word;
Tree* tree = new Tree();
while(word != "end")
   cin >> word;
   if(word == "end")
       break;
   
   tree->addNode(word);


cout << "In order traversal" << endl;
tree->inOrder(tree->Root());
cout << endl;

cout << "Pre order traversal" << endl;
tree->preOrder(tree->Root());
cout << endl;

cout << "Post order traversal" << endl;
tree->postOrder(tree->Root());
cout << endl;

delete tree;
_getch();
return 0;

【问题讨论】:

调试器。使用调试器。调试器将允许您执行每条语句,一次一个,并观察变量的值。使用调试器后,使用有关可疑语句的详细信息编辑您的帖子。 嗨@ThomasMatthews 我不太确定如何使用调试器。在 Visual Studio C++ Express 版本中是否有任何本地调试方法?感谢您的回复。 【参考方案1】:

在您的测试示例A B C D E F 中,您的树基本上是一个链表。首先,您插入A,因此它成为您的新根。 BA 大,所以当你插入它时,它会作为一个正确的孩子。所有下一个字符串都会发生同样的情况:

A->B->C->D->E->F.

因此,当您从左侧遍历树时,您只需按原样打印列表,因为树中的任何节点都没有左子节点。当你从右边遍历它时,你只需将它向后打印。

由于您的树不平衡,这是预期的行为。从我所见,您的代码中没有错误。尝试添加平衡或创建另一个根。

【讨论】:

那么如何在不排序的情况下制作一棵树?因为当我尝试所有输出时,我得到的都是奇怪的东西,比如AA F F。不能正常工作。 这是一棵树。即使是链表在技术上也是一棵树。如果你问如何制作一个 balanced 树(最大高度为 log(n) 的树),那么你必须为你的树实现平衡(google it)。我不明白您所说的“不排序就造树”是什么意思?您已经实现了一个有效的二叉搜索树。如果你只想要一棵始终为 log(n) 高度的树,请查看“堆(数据结构)”,但堆树不是二叉搜索树。 我的意思是,如果我想创建这样的树:d2vlcm61l7u1fs.cloudfront.net/… 我该怎么办?不让 B 向右走,C 向右走,D 向右走等等……一切都应该像图像中的那样。我没有这样做。 要么平衡你的树(艰难的方式),要么只是改变你的add 方法:使用广度优先遍历而不是深度优先遍历和在找到的第一个空白处插入新节点。

以上是关于为啥我的代码不能在二叉搜索树中正确执行预排序?的主要内容,如果未能解决你的问题,请参考以下文章

在二叉搜索树中查找高度

在二叉搜索树中找到一个节点的父节点

以最优方式在二叉搜索树中找到第 k 个最小元素

在二叉查找树中插入节点

在二叉搜索树中查找地板和天花板

如何在二叉树中返回迭代遍历的迭代器?