Вопрос: Я продолжаю получать сообщение об ошибке exc_bad_access (код процесса 11). Это из-за плохого алгоритма или просто ошибки кодирования? Может ли кто-нибудь помочь мне исправить это?
Мое задание на уроке — создать бинарное дерево поиска, узлы которого могут хранить имя, баланс и ключ. Узлы должны быть организованы и найдены с помощью ключа. Это дерево должно поддерживать вставку, неупорядоченный обход и поиск по ключу (эту функцию я еще не создал). Я также включил несколько других функций, чтобы облегчить их создание. Если это имеет значение, я использую CLion на OSX High Sierra. Кроме того, я получаю сообщение об ошибке при первом запросе на ввод информации об узле, ошибка, похоже, не связана с самим вводом.
//Genghis Khan
#include <iostream>
#include <vector>
using namespace std;
class node
{
public:
int key;
string name;
double balance;
node *leftptr;
node *rightptr;
friend class tree;
};
class tree
{
public:
node *root, *temp, *v;
//Constructor
tree()
{
root = NULL;
temp = root;
}
bool empty()
{
return(root == NULL);
}
bool isleaf(node *x)
{
return((x->leftptr == NULL) && (x->rightptr == NULL));
}
void inorder(node *temp)
{
if(~isleaf(temp))
{
inorder(temp->leftptr);
cout << "Name: " << temp->name << " " << "Balance: " <<
temp->balance << " " << "Key: " << temp->key;
inorder(temp->rightptr);
}
}
node* createnode()
{
v = new node;
cout << "Enter name (string): " << endl;
getline(cin, v->name);
cout << "Enter key (integer): " << endl;
cin >> v->key;
cout << "Enter balance (double): " << endl;
cin >> v->balance;
return(v);
}
void set()
{
temp = root;
}
void insert(node *v)
{
while(~isleaf(temp))
{
if((v->key < temp->key))
{
temp = temp->leftptr;
insert(v);
}
else if(v->key > temp->key)
{
temp = temp->rightptr;
insert(v);
}
}
temp->key = v->key;
temp->balance = v->balance;
temp->name = v->name;
}
};
int main()
{
int n;
cout << "Enter number of people: ";
cin >> n;
//Creating instance of tree, inserting all data into tree
tree b;
for(int i = 0; i < n; i++)
{
b.set();
node *a = b.createnode();
b.insert(a);
}
//inorder part
b.set();
b.inorder(b.temp);
}
Функции (псевдокод):
1. function isleaf(x): return(x's left pointer and x's right pointer are both NULL)
2. function set(): set temp to root //temp will be reset every time an insertion, traversal, or search occurs
3. function createnode():
v is a new node
get all the fields for v
return v
4. function insert(v)
while(not isleaf(temp)):
-if(v's key < temp's key)
temp = temp's left pointer (to the lower value child node)
insert(node *v)
-if(v's key > temp's key)
temp = temp's right pointer (to the higher value child node)
insert(node *v)
end while
duplicate v's data to temp, now that temp is a leaf
5. function inorder(temp):
if(not isleaf(temp):
inorder(temp's left pointer)
output all info in temp node
inorder(temp's right pointer)
Основной алгоритм
для количества вводимых узлов:
1. set
2. node *a = createnode
3. insert(a)
Обновлять
Похоже, ошибка исходит из строки «if ((v-> key ‹ temp-> key))».
if(~isleaf(temp))
выглядит странно. Зачем вам переворачивать логическое значение? Возможно, вам здесь нужноif(!isleaf(temp))
. g++ с -pedantic -Wall -Wextra помечает это предупреждением. Цепочка инструментов по умолчанию для xcode, clang, вероятно, также предупредит вас. - person user4581301   schedule 14.11.2017getline(cin, v->name);
пользователь, скорее всего, нажмет клавишу ввода вcin >> n;
, чтобы ввести значение дляn
и получить следующее приглашение.cin >> n;
прочитает и преобразует число (если оно конвертируемое. Вы не проверили. Упс.) и оставит конец строки от нажатия Enter, чтобыgetline(cin, v->name);
забрал.getline
мгновенно находит конец строки и выдает пустую строку. Затем имя будет прочитано дляkey
и прервет поток. Размещениеcin.ignore
послеcin >> n;
необходимо. - person user4581301   schedule 14.11.2017v
иtemp
указывают на допустимую память. - person user4581301   schedule 14.11.2017v
, которая выглядит так, как будто она затенена некоторой локальной переменнойv
s. Я не думаю, что вам это нужно как переменная-член. Также серьезно переосмыслите всю этуtemp
штуку. Вот что убивает вашу программу. Это почти наверняка NULL при первой вставке, потому что у вас еще нетroot
. - person user4581301   schedule 14.11.2017