Я хочу записать данные sh в двоичное дерево, но оно показывает ошибку сегментации после 3 входов - PullRequest
0 голосов
/ 15 января 2020

Это функция pu sh для ввода данных в двоичное дерево. Это вызывает ошибку сегментации при третьем вызове. Проверьте код для более.

void push(){
  int data;
  printf("enter the data you want to enter");
  scanf("%d",&data);
  struct bst* temp;
  temp=(struct bst*)malloc(sizeof(struct bst*));
  temp->data=data;
  if(root==NULL){
    temp->right=NULL;
    temp->left=NULL;
    root=temp;
  }else{
    struct bst* p;
    p=root;
    while(p->left!=NULL || p->right!=NULL){
      if(data<<p->data){
         p=p->left;
       }else{
         p=p->right;
       }
    }
    if(data>>p->data){
      temp->left=NULL;
      temp->right=NULL;
      p->right=temp;
    }else{
      temp->left=NULL;
      temp->right=NULL;
      p->left=temp;
    }
  }
}

Ответы [ 3 ]

1 голос
/ 15 января 2020

Существует множество проблем с представленным кодом, некоторые из которых были представлены в комментариях и в другом ответе. Среди них

  • Вы не выделяете достаточно места для каждого узла (для @EddInglis). В результате вы пишете за пределами выделенного объекта, когда устанавливаете один или несколько его членов, что приводит к неопределенному поведению. Вероятно, это источник segfaults . В качестве связанного, но второстепенного вопроса, в C вам не нужно явно преобразовывать значения типа void * в другие типы указателей объектов для присваивания, и в качестве стиля и хорошей практики программирования вам не следует этого делать.

  • Ваш условный лог c для обхода дерева неверен (для @hhusein). Условие p->left!=NULL || p->right!=NULL выполняется для всех узлов, которые не являются листьями, но вам также необходимо учесть случай внутренних узлов, у которых есть только один дочерний узел. Это, вероятно, не является причиной segfault, хотя. Он просто склонен к потере данных и утечке памяти.

  • Ваш условный лог c для выбора неверного направления движения в дереве:

       if(data<<p->data){
    

    ...

     if(data>>p->data){
    

    Операторы << и >> вычисляют битовые сдвиги влево и вправо. Вместо этого вы ищете реляционные операторы (< и >). Это не несет ответственности за ваш segfault, но это приведет к тому, что результирующее двоичное дерево не станет двоичным деревом search . Узлы будут расположены неправильно в большинстве случаев.

1 голос
/ 15 января 2020

При обходе дерева вы используете условие p->left!= NULL OR p->right!= NULL. В этом случае, если слева от вашего дерева не NULL, в этом случае вы назначаете NULL для p. Затем вы сравниваете данные с данными переменной NULL. Это вызывает ошибку сегментации. Вы должны добавить оператор AND вместо OR к условию while:

while(p->left!=NULL && p->right!=NULL){

Также в этой строке if(data>>p->data){ вы используете оператор сдвига вправо вместо оператора большего размера. Вы должны напечатать это правильно.

0 голосов
/ 15 января 2020

В вашем коде есть три опечатки:

  1. Ваш malloc выделяет размер указателя, чем узел. то есть mallo c (sizeof (struct bst))
  2. if(data<<p->data) смещает данные влево, а не сравнивает. Замените на просто сравнение if(data < p->data)
  3. if(data>>p->data) - оператор смещения вправо, и вам нужно if(data>p->data)

Помимо опечаток, logi c, чтобы найти нужного заполнителя для вновь созданного узла должен быть исправлен.

temp->left= NULL;
temp->right= NULL;
while(p){
    if(data < p->data){
       if(!p->left) {
           p->left = temp; 
           break;
           }
         p=p->left;
    }else if(data > p->data) { 
       if(!p->right) {
           p->right = temp; 
           break;
           }
       p=p->right; 
    }else{
       //Skip insertion for same key
       break;
    }
} 
...