Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 14.08.2009, 00:49   #1
lioshenka
 
Регистрация: 13.08.2009
Сообщений: 4
По умолчанию Двоичное дерево поиска структур

Есть проблема:

надо сделать программку, чтобы она считывала данные о человеке из файла, сохраняла их в структуры (с переменными имя, фамилия, телефон), а потом ощуществляла поиск по структурам с помощью двоичного дерева поиска. Ключ - фамилия. Поиск тоже осуществляется по фамилии.

Ума не приложу, как это сделать...

Накалякал тут немножко, но кажется, он только первые буквы фамилий считывает, и даже структуры не запихивает в ДДП.

Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct tree {
  char info;
  struct tree *left;
  struct tree *right;
};

struct tree *root; /* first node in tree */
struct tree *stree(struct tree *root,
                   struct tree *r, char info);
void print_tree(struct tree *root, int l);


int main()
{
     typedef struct{
            char dummy[256];
            char surname[225];
            char name[256];
            int ID;
            char house[256];
            char street[256];
            char town[256];
            char county[256];
            char area[256];
            char country[256];
            char postcode[256];
            int phone;
            char email[256];
            char boattype[256];
            char boatname[256];
            }user;
root = NULL;  /* initialise the root */
FILE *file;
int i=0;
char number_of_people[256];
int nop;
char yetdummy[256]; 
char yetdummy2[256]; 
char s[80];

  file = fopen("members.data","r");
 if(file==NULL) {
    printf("Error: can't open file.\n");
    return 1;
  }
  else {
    printf("File opened successfully.\n");
         }
 fscanf(file,"%s \n", number_of_people);
 //printf("%s \n", number_of_people);

 nop = atoi(number_of_people);
 //printf("%d\n", nop);
 user usera[nop]; 
 
  for (i=0; i<nop; i++){
  printf("Reading a structure...\n");
      fgets(usera[i].dummy, 256, file);        
      fgets(usera[i].surname, 256, file);  
      fgets(usera[i].name, 256, file);  
      fgets(yetdummy, 256, file);  
      usera[i].ID = atoi(yetdummy);      
      fgets(usera[i].house, 256, file);  
      fgets(usera[i].street, 256, file);  
      fgets(usera[i].town, 256, file); 
      fgets(usera[i].county, 256, file);  
      fgets(usera[i].area, 256, file);  
      fgets(usera[i].country, 256, file);  
      fgets(usera[i].postcode, 256, file);  
      fgets(yetdummy2, 256, file); 
      usera[i].phone = atoi(yetdummy2);
        
      fgets(usera[i].email, 256, file);  
      fgets(usera[i].boattype, 256, file);  
      fgets(usera[i].boatname, 256, file);        
     
     printf("Name is %s\n", usera[i].name);      
      printf("ID is %d\n", usera[i].ID); 
       root = stree(root, root, *usera[i].surname); 
    }
    fclose(file);

    
  //print_tree(root, 0);

  return 0;
}

struct tree *stree(
  struct tree *root,
  struct tree *r,
  char info)
{

  if(!r) {
    r = (struct tree *) malloc(sizeof(struct tree));
    if(!r) {
      printf("Out of Memory\n");
      exit(0);
    }
    r->left = NULL;
    r->right = NULL;
    r->info = info;
    if(!root) return r; /* first entry */
    if(info < root->info) root->left = r;
    else root->right = r;
    return r;
  }

  if(info < r->info)
    stree(r, r->left, info);
  else
    stree(r, r->right, info);
 
return root;
}
Компилятор, естественно, Dev C++. Язык - C.

Последний раз редактировалось lioshenka; 14.08.2009 в 00:52.
lioshenka вне форума Ответить с цитированием
Старый 14.08.2009, 15:23   #2
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Если дерево структур, то почему информационное поле типа char?
Код:
struct Tree {
  user *info;    //вот так надо
  struct tree *left;
  struct tree *right;
};
Далее...
Не уверен в структуре файла, но этот код можно заменить более простым
Код:
for (i=0; i<nop; i++){
  printf("Reading a structure...\n");
      fgets(usera[i].dummy, 256, file);        
      fgets(usera[i].surname, 256, file);  
      fgets(usera[i].name, 256, file);  
      fgets(yetdummy, 256, file);  
      usera[i].ID = atoi(yetdummy);      
      fgets(usera[i].house, 256, file);  
      fgets(usera[i].street, 256, file);  
      fgets(usera[i].town, 256, file); 
      fgets(usera[i].county, 256, file);  
      fgets(usera[i].area, 256, file);  
      fgets(usera[i].country, 256, file);  
      fgets(usera[i].postcode, 256, file);  
      fgets(yetdummy2, 256, file); 
      usera[i].phone = atoi(yetdummy2);
        
      fgets(usera[i].email, 256, file);  
      fgets(usera[i].boattype, 256, file);  
      fgets(usera[i].boatname, 256, file);
к примеру таким
Код:
fscanf(file, "%s%s%s%d%s%s%s%s%s%s%s%d%s%s%s", usera[i].dummy, usera[i].surname, usera[i].name, usera[i].ID, usera[i].house, usera[i].street, usera[i].town, usera[i].county, usera[i].area, usera[i].country, usera[i].postcode, usera[i].phone, usera[i].email, usera[i].boattype, usera[i].boatname);
Согласен, не сильно понятно, но места занимает меньше и преобразование типов делать не нужно
А можно вообще сделать просто, но тогда прийдется открывать файл потоково
Код:
ifstream in("members.data", ios_base::in);
in >> usera[i].dummy >> usera[i].surname >> usera[i].name >> usera[i].ID >> usera[i].house >> usera[i].street >> usera[i].town >> usera[i].county >> usera[i].area >> usera[i].country >> usera[i].postcode >> usera[i].phone >> usera[i].email >> usera[i].boattype >> usera[i].boatname;
ПыСы: не заметил что язык Си. Последний метод отпадает.
MaTBeu вне форума Ответить с цитированием
Старый 15.08.2009, 01:18   #3
lioshenka
 
Регистрация: 13.08.2009
Сообщений: 4
По умолчанию

Код:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

 typedef struct{
            char dummy[256];
            char surname[225];
            char name[256];
            int ID;
            char house[256];
            char street[256];
            char town[256];
            char county[256];
            char area[256];
            char country[256];
            char postcode[256];
            int phone;
            char email[256];
            char boattype[256];
            char boatname[256];
            }user;
            
struct tree {
  user *info;
  struct tree *left;
  struct tree *right;
};

struct tree *root; /* first node in tree */
struct tree *stree(struct tree *root,
                   struct tree *r, char info);
//void print_tree(struct tree *root, int l);


int main()
{
    
root = NULL;  /* initialise the root */
FILE *file;
int i=0;
char number_of_people[256];
int nop;
char yetdummy[256]; 
char yetdummy2[256]; 
char s[80];

  file = fopen("members.data","r");
 if(file==NULL) {
    printf("Error: can't open file.\n");
    return 1;
  }
  else {
    printf("File opened successfully.\n");
         }
 fscanf(file,"%s \n", number_of_people);
 //printf("%s \n", number_of_people);

 nop = atoi(number_of_people);
 //printf("%d\n", nop);
 user usera[nop]; 
 
  for (i=0; i<nop; i++){
  printf("Reading a structure...\n");
      fgets(usera[i].dummy, 256, file);        
      fgets(usera[i].surname, 256, file);  
      fgets(usera[i].name, 256, file);  
      fgets(yetdummy, 256, file);  
      usera[i].ID = atoi(yetdummy);      
      fgets(usera[i].house, 256, file);  
      fgets(usera[i].street, 256, file);  
      fgets(usera[i].town, 256, file); 
      fgets(usera[i].county, 256, file);  
      fgets(usera[i].area, 256, file);  
      fgets(usera[i].country, 256, file);  
      fgets(usera[i].postcode, 256, file);  
      fgets(yetdummy2, 256, file); 
      usera[i].phone = atoi(yetdummy2);
        
      fgets(usera[i].email, 256, file);  
      fgets(usera[i].boattype, 256, file);  
      fgets(usera[i].boatname, 256, file);        
     
     printf("Name is %s\n", usera[i].name);      
      printf("ID is %d\n", usera[i].ID); 
       root = stree(root, root, *usera[i].surname); 
    }
    fclose(file);

    
  //print_tree(root, 0);

  return 0;
}

struct tree *stree(
  struct tree *root,
  struct tree *r,
  char info)
{

  if(!r) {
    r = (struct tree *) malloc(sizeof(struct tree));
    if(!r) {
      printf("Out of Memory\n");
      exit(0);
    }
    r->left = NULL;
    r->right = NULL;
    r->info = info->surname;
    if(!root) return r; /* first entry */
    if(info < root->info) root->left = r;
    else root->right = r;
    return r;
  }

  if(info < r->info)
    stree(r, r->left, info);
  else
    stree(r, r->right, info);
 
return root;
}
Спасибо!
Вот сделал, как ты посоветовал, но выдаёт ошибку тут - ошибка "Base operand of -> is not a pointer". Это значит, что info не указатель? Вроде я правильно его прописал в начале!
lioshenka вне форума Ответить с цитированием
Старый 15.08.2009, 12:18   #4
MaTBeu
Eclipse Foundation
Старожил
 
Аватар для MaTBeu
 
Регистрация: 19.09.2007
Сообщений: 2,604
По умолчанию

Все правильно, потому что у r нету члена surname. Он есть у r->info
Короче надо написать вот так
Код:
strcpy(r->info->surname, info); //строки копируются функцией strcpy или lstrcpy(чтобы VC++ не ругался, что strcpy небезопасно копирует строки)
Но... если вы хотите присвоить целую структуру, то нужно и передавать структуру, а вы передаете мало того, что не строку а символ, так еще и пытаетесь присвоить структуре строку.
Код:
struct tree *stree(
  struct tree *root,
  struct tree *r,
  user *info_) //лучше переименовать переменную, чтобы не было конфликтов
И тогда ваша функция немного преобразится
Конец вашей функции прийдется переписать, потому что строки сравнивать операторами меньше/больше нельзя, для этого есть функция strcmp(или ее безопасный вариант для VC++ lstrcmp)

Последний раз редактировалось MaTBeu; 15.08.2009 в 12:23.
MaTBeu вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Двоичное деление neomichi Общие вопросы C/C++ 3 16.04.2009 21:32
Двоичное дерево afeg Паскаль, Turbo Pascal, PascalABC.NET 0 19.12.2008 14:49
Дерево цифрового поиска Alar Общие вопросы Delphi 2 10.07.2008 10:58
Двоичное сложение Юлкунчик Помощь студентам 5 29.02.2008 20:34