我真的被困了,我在“CTree.add(num);”收到错误说'CTree'是未声明的,这没有意义,因为我在tree.h中初始化它?
该程序应该提示用户,用户输入一个命令(即“添加3”,只有0-9个整数),然后我希望它将该数字插入树中。
//File: tree.h
class CTree
{
private:
CTree* m_pLeft;
CTree* m_pRight;
CTree* m_pRoot;
int m_nData;
public:
CTree();
bool isEmpty() const { return m_pRoot; }
bool search(int);
void print_inorder();
void inorder(CTree*);
void Add(int);
void remove(int);
void height();
};
//File: CTree.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
CTree::CTree()
{
m_pRoot=NULL;
}
bool CTree::search(int x)
{
if(x==m_nData) return true;
if(x < m_nData){ //go left
if(m_pLeft != NULL) //if possible
return m_pLeft->search(x);
}
else //go right
if(m_pRight != NULL) //ifpossible
return m_pRight->search(x);
return false;
}
void CTree::Add(int x)
{
CTree* t = new CTree;
CTree* parent;
t->m_nData = x;
t->m_pLeft = NULL;
t->m_pRight = NULL;
parent = NULL;
if(isEmpty()) m_pRoot = t;
else
{
//insert leaf nodes
CTree* leaf;
leaf = m_pRoot;
// find parent
while(leaf)
{
parent = leaf;
if(t->m_nData > leaf->m_nData)
leaf = leaf->m_pRight;
else
leaf = leaf->m_pLeft;
}
if(t->m_nData < parent->m_nData)
parent->m_pLeft = t;
else
parent->m_pRight = t;
}
}
void CTree::remove(int x)
{
bool found = false;
if(isEmpty())
{
cout<< "Tree is empty!" <<endl;
return;
}
CTree* current;
CTree* parent;
current = m_pRoot;
while(current != NULL)
{
if(current->m_nData == x)
{
found = true;
break;
}
else
{
parent = current;
if(x > current->m_nData) current = current->m_pRight;
else current = current->m_pLeft;
}
}
if(!found)
{
cout<< "Not found!" <<endl;
return;
}
// Node with single child
if((current->m_pLeft == NULL && current->m_pRight != NULL)|| (current->m_pLeft != NULL&& current->m_pRight != NULL))
{
if(current->m_pLeft == NULL && current->m_pRight != NULL)
{
if(parent->m_pLeft == current)
{
parent->m_pLeft = current->m_pRight;
delete current;
}
else
{
parent->m_pRight = current->m_pRight;
delete current;
}
}
else // left child present, no right child
{
if(parent->m_pLeft == current)
{
parent->m_pLeft = current->m_pLeft;
delete current;
}
else
{
parent->m_pRight = current->m_pLeft;
delete current;
}
}
return;
}
//We're looking at a leaf node
if( current->m_pLeft == NULL && current->m_pRight == NULL)
{
if(parent->m_pLeft == current) parent->m_pLeft = NULL;
else parent->m_pRight = NULL;
delete current;
//Node with 2 children
// replace node with smallest value in right subtree
if (current->m_pLeft != NULL && current->m_pRight != NULL)
{
CTree* check;
check = current->m_pRight;
if((check->m_pLeft == NULL) && (check->m_pRight == NULL))
{
current = check;
delete check;
current->m_pRight = NULL;
}
else // right child has children
{
//if the node's right child has a left child
// Move all the way down left to locate smallest element
if((current->m_pRight)->m_pLeft != NULL)
{
CTree* lcurrent;
CTree* lcurrent_parent;
lcurrent_parent = current->m_pRight;
lcurrent = (current->m_pRight)->m_pLeft;
while(lcurrent->m_pLeft != NULL)
{
lcurrent_parent = lcurrent;
lcurrent = lcurrent->m_pLeft;
}
current->m_nData = lcurrent->m_nData;
delete lcurrent;
lcurrent_parent->m_pLeft = NULL;
}
else
{
CTree* tmp;
tmp = current->m_pRight;
current->m_nData = tmp->m_nData;
current->m_pRight = tmp->m_pRight;
delete tmp;
}
}
return;
}
}
}
void CTree::print_inorder()
{
inorder(m_pRoot);
}
void CTree::inorder(CTree* x)
{
if(x != NULL)
{
if(x->m_pLeft) inorder(x->m_pLeft);
cout<<" "<<x->m_nData<<" ";
if(x->m_pRight) inorder(x->m_pRight);
}
else return;
}
//File: main.cpp
#include <iostream>
#include <cstdlib>
#include <sstream>
#include <locale>
#include <string>
#define PROMPT "bst> "
using namespace std;
int getNumber(string s)
{
int num;
for(int i; i<=s.length();i++)
{
if(isdigit(s[i]))
{
num= s[i]-48;
}
}
return num;
} // getNumber
bool process(const string& s, CTree* aTree)
{
bool mustquit=false;
int num;
istringstream iss(s);
do
{
string sub;
iss >> sub; //
if(sub=="add" || sub=="insert")
{
num=getNumber(s);
cout<<num<<endl;
aTree->Add(num);
}
else if(sub=="delete" || sub=="remove")
{
num=getNumber(s);
cout<<num<<endl;
}
else if(sub=="search" || sub=="find")
{
num=getNumber(s);
cout<<num<<endl;
}
else if(sub=="height")
{
//do stuff
}
else if (sub=="quit")
return mustquit;
//else cout<<"INPUT ERROR"<<endl;
} while (iss);
return mustquit;
}// process
int main(){
string input="";
CTree *myTree;
myTree = new CTree();
bool finished=false;
int i;
cout<<PROMPT;
while(!finished)
{
if(input!="")cout<<PROMPT;
getline(cin,input);
finished=process(input, myTree);
delete myTree;
}//while
return 0;
}
答案 0 :(得分:5)
add
是一个非静态成员函数,这意味着您只能在CTree
的实例上调用它。 e.g。
CTree myTree;
myTree.add(num);
答案 1 :(得分:1)
您知道您需要类CTree
的实例来实际使用它吗?你假设你正在一个类的实例上运行,你写了整个事情。实际的树,而不是蓝图。
正如我前面的回答所说,它不是静态函数或类级别。需要在实例上调用非静态方法,以便可以将静默指针this
设置为有意义的内容,即。您正在使用的实际实例 - 在这种情况下添加节点。
<强>附录强>
(下面的所有内容都可以在不修改你的代码的情况下工作,只是对你的问题的明确答案,使其编译。从“工作的角度来看”,这个程序远非完整。有些部分甚至没有意义,许多变量未被使用或未初始化(然后使用)。让我在下面进一步阐述。)
你需要做的就是在主进程中发生旧的process()调用:
CTree myTree; // you could also add (), even though it's a default constructor
finished=process(input, myTree);
修改函数进程的参数列表,以包含对您希望操作的树的引用。这只是其中一种可能性,您也可以使用指针等。但参考更清晰:
bool process(const string& s, CTree& aTree)
另外,请注意编译器警告。良好的做法是照顾所有这些。请记住,这使得它编译,而不是工作。它似乎没有完成,边缘粗糙。
并记住一个类(一个想法)和一个实例(该想法的表现形式)之间的区别。技术细节现在并不重要,只要确保你有一个实例可以使用,就像你的类设计一样。在我看来,你无法掌握计算机软件的工作原理,操作它的数据和指令是如何连接的,特别是从记忆的角度来看。计算机知道你想做什么是不够的,它需要知道你想要执行什么操作(哪些变量或对象或者你有什么)。您可以按值复制并返回,在main函数中执行,传递引用或带有地址的指针,以便它可以知道您的对象/实例所在的内存位置等。如果您只是在尝试,则可以创建一个全局实例。很多选择。
重新声明一切都不会带来之前发生的变化(因为东西超出了范围)。
,在类级别调用非静态成员方法也没有意义。希望它有助于编码。坚持下去,没有什么值得做的很简单。
答案 2 :(得分:0)
我认为他们对你的经验水平有点过于技术化。 YourCTree类代码创建了一个CTree类及其行为(蓝图),但实际上你必须告诉你的代码构造一个,然后有一种方法来引用它。
您可以像这样声明堆栈变量实例:
CTree myTree;
这为您的类分配内存,并在进入函数时调用构造函数。然后,您可以使用点表示法从实例名称引用函数来使用它。
myTree.Add(4);
或者您可以声明指向CTree的指针并使用new运算符
创建动态实例CTree *myTree;
myTree = new CTree();
然后使用指针表示法引用树:
myTree->Add(4);
如果你这样做,你需要删除你分配的内存
delete myTree;
总而言之,这里展示的类的类定义描述了一个类,但没有创建一个类(为方法代码分配内存和设置指针)。如果您的代码逻辑需要,这允许您拥有许多树;
CTree directoryTree;
CTree fileTree;
CTree indexTree;
这些都有自己的数据......
祝你好运,