в C ++, для чего это? Узел * и голова,

0

У меня есть вопрос относительно этой части кода. Node* &head, в функции insert(), мне трудно понять смысл этого. Является ли это "ссылкой на указатель на структуру узла"?

Но почему здесь getDepth(Node *head) он использует Node *head? Это хорошая практика? какой лучший способ написать, если это возможно?

Спасибо!

#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

const int maxn = 100;
struct Node{
    int key;
    Node *lchild, *rchild, *parent;
};
Node *head, *p, node[maxn];
int cnt;

void init(){
    head = p = NULL;
    memset(node, '\0', sizeof(node));
    cnt = 0;
}
void insert(Node* &head, int x){
    if(head == NULL){
        node[cnt].key = x;
        node[cnt].parent = p;
        head = &node[cnt++];
        return;
    }
    p = head;
    if(x < head->key)
        insert(head->lchild, x);
    else
        insert(head->rchild, x);
}
int d = 0, num = 0, dep[maxn];
void getDepth(Node *head){
    if(head == NULL) return;
    ++d;
    getDepth(head->lchild);
    if(head->lchild == NULL && head->rchild == NULL)
        dep[num++] = d;
    getDepth(head->rchild);
    --d;
}
bool isBalance(Node *head){
    if(head == NULL) return true;
    getDepth(head);
    int max = dep[0], min = dep[0];
    for(int i=0; i<num; ++i){
        if(dep[i]>max) max = dep[i];
        if(dep[i]<min) min = dep[i];
    }
    if(max-min > 1) return false;
    else return true;
}
int main(){
    init();
    int a[] = {
        5, 3, 8, 1, 4, 7, 10, 2, 6, 9, 11, 12
    };
    for(int i=0; i<12; ++i)
        insert(head, a[i]);
    cout<<isBalance(head)<<endl;
    return 0;
}
Теги:

5 ответов

2
Лучший ответ

Если вы передаете Node *head вместо Node* &head, и если "head" будет изменен, изменение не будет доступно в main функции.

Если вы хотите, чтобы эти изменения были доступны, вы return head или пропустите Node* &head или Node **head.

В getDepth() нет необходимости менять указатель "head". Итак, прохождение Node *head отлично работает.

1

Именно это и есть: ссылка на указатель на Node. Он позволяет передавать в Node* по ссылке, так что, когда вы изменяете указатель внутри функции, модификация будет видна снаружи.

Простой пример с эталонным параметром:

void inc(int& x) {
  x++;
}

Если у меня есть переменная int y = 0; , передайте его с помощью inc(y), а затем проверьте значение y после этого, оно будет иметь значение 1. Если параметр не был ссылочным типом, значение было бы 0, потому что только копия внутри inc была бы изменена.

Ваше дело точно так же. Вы передаете Node* по ссылке, чтобы вы могли изменить указатель и видеть его снаружи.

1

Эта конструкция означает ссылку на переменную с типом Node *. Проблема в том, что если вы просто объявляете этот параметр функции insert как Node *, то внутри функции этот параметр bahaves как локальная переменная. Таким образом, любые изменения в нем будут потеряны после выхода из функции. Таким образом, в этом случае исходная переменная голова не будет изменена. Передача указателя по ссылке гарантирует, что любые изменения в голове внутри функции будут сохранены в исходной переменной.

0

Вы смотрите на ссылку на указатель.

http://en.wikipedia.org/wiki/Reference_(C%2B%2B)

Я бы избегал использовать ссылки, так как они неотличимы от передачи чего-то по значению при вызове.

  • 0
    Избегать использования ссылок? Whaaaaat?
  • 0
    Вы имеете в виду только с указателями?
Показать ещё 1 комментарий
0

Человек, который написал этот код, является рывком и написал нечитаемый код. Просто ужасно.

Однако Node * & head является ссылкой на указатель на узел. Таким образом, в основном он передает указатель на голову по ссылке, поэтому вы можете изменить значение главы ptr.

Например:

Node *A = NULL;
insert(A,10);
//now A has changed, A != NULL;
  • 1
    так что если бы вы написали это, что бы вы написали? Спасибо!
  • 0
    @NoName: возможно, struct List { Node* head; }; а затем insert() будет принимать List& . Или даже просто typedef Node* List;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню