0

二分探索木からノードを削除しようとしています。しかし、関数をテストしたい場合、「ケース 3: 2 人の子供」でエラー メッセージが表示されます。

clist->name = temp->name;

この行により、エラー メッセージが表示されます。それは言います:左オペランドは左辺値でなければなりません。私はCと二分探索木が初めてです。なぜこの行が機能しないのかわかりません。削除機能を実装する方法について、インターネット上で多くのアイデアを見つけました。そして、これらのアプローチはすべて、このコード行を使用します。

以下は完全な関数です。

(greaterThan、lessThan、toLowerCase は私が実装したヘルパー関数です。確かに正常に動作しています)

struct student {
    int ID;
    char name[20];
    struct student *left;
    struct student *right;
};

struct student * minValueNode(struct student* node) {
    struct student* current = node;
    while (current->left != NULL)
        current = current->left;

    return current;
}

struct student * bst_delete (struct student *clist, char* token, struct student **parent)
{

  if (clist == NULL)
      return clist;

  char* clistName = clist->name;
  char* tok = token;
  toLowerCase(clistName);
  toLowerCase(tok);

  if (lessThan(tok, clistName))
      clist->left = bst_delete(clist->left, token, &clist->left);

  else if (greaterThan(tok, clistName))
      clist->right = bst_delete(clist->right, token, &clist->right);

  else
  {
      //Case 1: No children
      if (clist->left == NULL && clist->right == NULL) {
          free(clist);
          clist = NULL;
      }
      //Case 2: One Child
      if (clist->left == NULL) {
          struct student *temp = clist;
          clist = clist->right;
          free(temp);
      } else if (clist->right == NULL) {
          struct student *temp = clist;
          clist = clist->left;
          free(temp);
      }
      //Case 3: Two Children
      else {
          struct student *temp = minValueNode(clist->right);
          clist->name = temp->name;
          clist->right = bst_delete(clist->right, temp->right, &clist->right);
      }

  }
  return clist;
}

この行が機能しない理由を誰かに教えていただければ幸いです。そして、このエラーを修正する方法。

ありがとう!

4

1 に答える 1

1

直接代入を介してcで配列をコピーすることはできません。本当にやりたいことは、配列の要素をコピーすることです-そのためには、strcpyを使用できます-

strcpy(clist->name, temp->name);

または、サイズが一定であるため、少し安全な -

strncpy(clist->name, temp->name, 20);

実際、あなたはここで幸運でした。名前文字列にポインターを使用して (それらを動的に割り当て)、その割り当てを有効なコードにすることができました (ただし、文字列の内容を必要に応じてコピーすることはなく、1 つのポインターを別のポインターでオーバーライドするだけです)。コードをコンパイルできるようにしますが、メモリ リークが発生し、ノード間でポインタが共有されるため、デバッグがはるかに困難になります。

この場合、割り当ての右側の値はポインターに減衰する可能性がありますが、左側の値はそれができません (その配列は構造体内に静的に配置されるため)。そのため、コンパイラーは左辺値について不平を言っています。

于 2015-11-06T01:02:36.153 に答える