C - Позвонить по ссылке - PullRequest
       28

C - Позвонить по ссылке

1 голос
/ 04 декабря 2011

Я написал простую программу, которая сортирует числа по одному для их повторения, а затем вставляет их по одному в дерево.Моя проблема в том, что я не мог вставить дочерние элементы root, потому что я не мог изменить приведенную ниже функцию на тип вызова по ссылке.

q параметр ниже должен содержать значение адреса корня, я думаю.

void insertNode(int data, node *q, node *parent){
    if(q == NULL){
        node *p = createNode(data);
        p -> parent = parent;
        p -> key = generateKey(p);
        int i;
        for(i = 0;table[i][1] != 0;i++);
        table[i][1] = p -> data;
        table[i][0] = p -> key;
        q = p;
    }
    else if(q -> left > q -> right || q -> left == q -> right){
        q -> right++;
        insertNode(data, q -> rightChild, q);
    }
    else if(q -> right > q -> left){
        q -> left++;
        insertNode(data, q -> leftChild, q);
    }
}

Ответы [ 3 ]

7 голосов
/ 04 декабря 2011

В C. нет такой вещи, как "передача по ссылке". Если вам нужно присвоить новое значение указателю, переданному в функцию (а не просто изменить то, на что указывает указатель), вы будете делать это. нужно передать указатель на указатель, т. е.

void insertNode(int data, node **q, node *parent){
    /* code */
    *q = p;
}

Когда вы передаете указатель (или что-то еще) в C, вы передаете копию указателя. Итак, этот тип изменения виден для вызывающих абонентов вашей функции:

q->someVal = someOtherVal;

но это не потому, что вы изменяете только копию, переданную функции:

q = p;

Вам нужно добавить еще один уровень косвенности, чтобы изменить сам аргумент так, чтобы это изменение было видно за пределами функции.

2 голосов
/ 04 декабря 2011

Узел, выделенный в "if (q == NULL) { } "блок потерян; как только функция возвращается, для него нет доступного указателя на нее (q = p; присваивание ничего не делает)

ОБНОВЛЕНИЕ: ** p также позволяет удалить рекурсию:

void insertNode(int data, node **qRef, node *parent){
  node *q;
  int i;

  for (   ; (q = *qRef) ; parent=q ) {
    if(q->left >= q->right) {
      q->right++;
      qRef = &q->rightChild;
    }
    else {
      q->left++;
      qRef = &q->leftChild;
    }
  }


  *qRef = q = createNode(data);
  q->parent = parent;
  q->key = generateKey(q);

  for(i=0; table[i][1] != 0; i++) {;}
  table[i][1] = q->data;
  table[i][0] = q->key;

}
0 голосов
/ 04 декабря 2011

Как насчет этого?

void insertNode(int data, node **qRef, node *parent){
  node *q = *qRef; //<-- changed
  if(q == NULL){
    node *p = createNode(data);
    p -> parent = parent;
    p -> key = generateKey(p);
    int i;
    for(i = 0;table[i][1] != 0;i++);
    table[i][1] = p -> data;
    table[i][0] = p -> key;
    *qRef = p; //<-- changed
  }
  else if(q -> left > q -> right || q -> left == q -> right){
      q -> right++;
      insertNode(data, &(q -> rightChild), q); //<-- changed
  }
  else if(q -> right > q -> left){
      q -> left++;
      insertNode(data, &(q -> leftChild), q);  //<-- changed
  }
}
...