#c #pointers #binary-search-tree
#c #указатели #двоичное дерево поиска
Вопрос:
Предоставленный мной код является простым BST только с обходом по вставке и порядку.
struct Node{
int data;
Node* left;
Node* right;
};
Node* create(int data){
Node* node = new Node;
node -> data = data;
node->left=node->right=NULL;
return node;
}
Node* insert(Node* ptr,int item);
void inorder(Node* ptr);
int main(){
Node* root = NULL;
int temp,ch;
root = insert(root, 10);
root = insert(root, 20);
root = insert(root, 30);
inorder(root);
cout<<endl;
}
Node* insert(Node* ptr,int item){
if(ptr==NULL){
cout<<"Inserted "<<item<<endl;
return create(item);
}
if(item<ptr->data){
// ptr = ptr->left;
// ptr = insert(ptr, item)
ptr->left=insert(ptr->left, item);
}
else{
// ptr=ptr->right;
// ptr = insert(ptr, item)
ptr->right=insert(ptr->right, item);
}
return ptr;
}
void inorder(Node* ptr){
if(ptr==NULL)
return;
inorder(ptr->left);
cout<<ptr->data<<" ";
inorder(ptr->right);
}
когда я использую,
ptr = ptr->left;
ptr = insert(ptr, item)
вместо
ptr->left=insert(ptr->left, item);
При обходе по порядку печатается только последний вставленный элемент.
Пожалуйста, объясните, является ли это проблемой c или я неправильно понимаю эту концепцию?
Комментарии:
1. один из них — «скопируйте значение ptr->left в ptr, измените ptr», другой — «измените ptr->left».
2.
ptr
является локальной переменной. Переназначение его (согласно вашей первой версии) не влияет ни на какой другой объект3. Попробуйте пошагово выполнить код с помощью отладчика.
Ответ №1:
Важной частью кода является:
Node* insert(Node* ptr,int item){
Для пояснения рассмотрим, что вы называете это так:
Node x;
Node* p = amp;x;
insert(p, 42);
Здесь p
передается по значению. Это указатель. Если вы измените ptr
, то изменения будут применяться только к локальному, ptr
а не к p
.
Однако, если вы присваиваете значение ptr->first
, то вы изменяете объект, на который указывает ptr
. И хотя указатель передается по значению, ptr
указывает на тот же объект, что и p
. То есть: ptr->first = something;
внутри функции действительно изменяет член x
.
Ответ №2:
ptr->left=insert(ptr->left, item);
Изменит содержимое ptr
объекта. Он выполняет вставку и сохраняет ее.
Однако, когда вы делаете:
ptr = ptr->left;
ptr = insert(ptr, item)
сначала вы получаете указатель на то, на что ptr->left
указывал, вы вставляете таким же образом. Но возвращаемое значение не сохраняется в вашем исходном ptr
объекте.
Итак, в этом нет ничего странного. Единственный известный мне способ полностью понять это — нарисовать дерево. Создайте окно, показывающее объект, и указатель на него, и для каждой операции обновляйте свой чертеж. Это должно стать понятным.