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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.05.2010, 19:04   #1
frmSm
Пользователь
 
Регистрация: 30.05.2010
Сообщений: 12
По умолчанию Не получается удалить узел дерева.

после удаления всё равно выводятся некоторые элементы узла.
Код HTML:
#include <iostream>
#include <stdio.h>
using namespace std;

#define sz 10

struct Item{
       int release;
       char *string;
       Item *next;
       };

struct Node{
       int key;
       Item *info;
       Node *left, *right;
       };
       
char * Messages[] = {
     "\n2) View	\n",	
	"3) Input	\n",		
	"1) Delete	\n",		
			
	//"5) Exit	\n"			
};

int MessagesCount = sizeof(Messages) / sizeof(Messages[0]);		

int Menu() {		
	int answer = 1;
	do {
		for (int i = 0; i < MessagesCount; i++)
			cout << Messages[i];
		cout << "Please, select menu item: ";
		cin >> answer;
	} 
    while (answer < 1 || answer > MessagesCount);
	return answer % MessagesCount;
} 



void Insert(Node*&);							
void Delete(Node*&);			
void View(Node*&);				
//void Quit(Node*);				

Item *CreateItem(int , char *);

void (*func[])(Node*&) = {		
//	Quit,
	Insert,
    Delete,
	View
};

    
//Ñîçäàíèå ýëåìåíòà     
Item *CreateItem(int release, char *str)
{
	Item *item = new Item;
	item->release = release;
	item->string = new char[strlen(str) + 1];
	strcpy(item->string, str);
	item->next = NULL;
	return item;
}

//Ñîçäàíèå óçëà
void input(Node** tree,Item *itm,int key) {
     if (*tree==NULL) {
        *tree=new Node;
        (*tree)->key=key;    
        (*tree)->info=itm;
        (*tree)->left=NULL;
        (*tree)->right=NULL;
        }
     else
         if(key < (*tree)->key) 
                              input(&((*tree)->left), itm, key);
                              else
         if(key > (*tree)->key) 
                              input(&((*tree)->right), itm, key);
                              }

Item *appItem(Item *itm,int release, char *str) {
     if ((itm->next))
     appItem(itm->next,release,str);
     else 
     itm->next=CreateItem(release,str);
     }
     
//Ïîèñê óçëà ïî êëþ÷ó    
int findkey(Node *tree,int key,int release, char *str) {
    if(tree!=NULL) {
	       if((tree)->key==key) {
                              appItem(tree->info,release,str); 
/*                    while(tree->info) {
                            if((tree->info->next)) {
                             tree->info=tree->info->next; }
                            else {    
                   (tree)->info->next=CreateItem(release,str);} }  
                   //(tree)->info=(tree)->info->next;*/
		           return 1;
                   } 
	            
    if (tree->key!=key) {
     findkey(((tree)->left),key,release,str);
     findkey(((tree)->right),key,release,str);
     } }
     return 0;
} 

int findkeyThenDel(Node *tree,int key) {
    if(tree!=NULL) {
	       if((tree)->key==key) {
                          Node *tmp=new Node;
                          //Item *itm=new Item;
                          //itm=*&(tree->info);
                          tmp->right=tree->right;
                          tmp->left=tree->left;
                          //delete ((*tree)->info);
                           delete *&tree;
                           tree=NULL;
                          // free(itm);
//                          delete tmp;      
		           return 1;
                   } 
	            
    if ((tree)->key!=key) {
     findkeyThenDel(((tree)->left),key);
     findkeyThenDel(((tree)->right),key);
     } }
     return 0;
}


Item *viewItem(Item *itm) {
     for(;;) {
                      cout<<"\t" << itm->release << "\t" << itm->string 
                      << endl;
                      itm=itm->next;
                      if(!(itm)) break;
                      } }                      
     

void treeView(Node*& tree) {

     if (tree != NULL) {
     cout<<tree->key ;
     viewItem(tree->info);
     // endl ;
     treeView(tree->left);
     treeView(tree->right);
		 } 
         else return; }      
                       
void View(Node*& tree) {
     cout << "key\t" << "Release\t" << "String" << endl;   
     treeView(tree);
     }




void Insert(Node *&tree) 
{
   	Item *itm=NULL;
	int key;
	int release;
	int aa;
	char string[80];
	cout << "\nVvedite key    : "; cin >> key;
    cout << "\nVvedite release: "; cin >> release;
	cout << "\nVvedite string : "; cin >> string;
	itm=CreateItem(release,string);
	if (findkey(tree,key,release,string)) return;
    input((&tree),itm,key); 
}

void Delete(Node *&tree) {
     int key;
     cout << "\nInser key for del : ";
     cin >> key; cout <<endl;
     if(findkeyThenDel(tree,key))
     
     cout << "node deleted" << endl;
     else
     cout << "No key in tree" << endl;
     }
     
int main()
{
	setlocale(LC_ALL, "Russian");
			
	Node *tree=NULL;
  				
	for(;;) {
	int answer = 1;
	do {							
		answer = Menu();
		func[answer](tree);	
	} while (answer);
}
    return 0;
}
frmSm вне форума Ответить с цитированием
Старый 30.05.2010, 19:11   #2
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

А некоторую присказку лень написать? Что делаете, где удаляете, как удаляете, что выводится, что должно выводиться и т.д.?
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 30.05.2010, 19:25   #3
frmSm
Пользователь
 
Регистрация: 30.05.2010
Сообщений: 12
По умолчанию

Хм, да , что то я....

Последний раз редактировалось frmSm; 30.05.2010 в 19:28.
frmSm вне форума Ответить с цитированием
Старый 30.05.2010, 19:27   #4
frmSm
Пользователь
 
Регистрация: 30.05.2010
Сообщений: 12
По умолчанию

))). вот сама функция удаления
Удаление узла должно происходить в том случае , если найден его ключ. Но так выходит что при использовании функции удаляется только ключ, а элемент (release и string) не удаляется и выводится с 0 ключём. Удаляю я рекурсивно пробегаясь по дереву в поиске ключа.

Код:
int findkeyThenDel(Node *tree,int key) {
    if(tree!=NULL) {
	       if((tree)->key==key) {
                          Node *tmp=new Node;
                          tmp->right=tree->right;
                          tmp->left=tree->left;
                           delete *&tree;
                           tree=NULL;     
		           return 1;
                   } 
	            
    if ((tree)->key!=key) {
     findkeyThenDel(((tree)->left),key);
     findkeyThenDel(((tree)->right),key);
     } }
     return 0;
}
tmp->right и tmp->left я планирую использовать для связи оторванных узлов
frmSm вне форума Ответить с цитированием
Старый 30.05.2010, 19:45   #5
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

В вашем коде разобраться трудно - начиная с объявления переменной в теле цикла, кончая парой компиляционных ошибок.
Каким образом "при использовании функции удаляется только ключ, а элемент (release и string) не удаляется и выводится с 0 ключём", если код вообще не запускается?
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 30.05.2010, 19:46   #6
Ozerich
Студент 1 курса
Форумчанин Подтвердите свой е-майл
 
Аватар для Ozerich
 
Регистрация: 27.06.2008
Сообщений: 959
По умолчанию

Если дерево должно поддерживать удаление, то кроме левого и правого сына должен еще и указатель на предка храниться. И в дереве всегда правый сын больше чем его предок, соответственно левый сын всегда меньше чем его предок. Это значит что не надо обоих сыновей просматривать.
C++(STL, QT, WinInet) / DHTML(CSS) / JavaScript / PHP Developer
Ozerich вне форума Ответить с цитированием
Старый 30.05.2010, 19:56   #7
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Легче проверять на равенство ключу не данный узел, а его потомков: тогда удаление в случае находки нужного потомка заключается в создании нового дерева с корнем в предке удаленного и всеми ответвлениями удаляемого узла и присоединении его к этому предку. Но вообще код серьезно недоработан.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."

Последний раз редактировалось Syuf; 30.05.2010 в 19:59.
Syuf вне форума Ответить с цитированием
Старый 30.05.2010, 20:14   #8
frmSm
Пользователь
 
Регистрация: 30.05.2010
Сообщений: 12
По умолчанию

Цитата:
Сообщение от Ozerich Посмотреть сообщение
Если дерево должно поддерживать удаление, то кроме левого и правого сына должен еще и указатель на предка храниться. И в дереве всегда правый сын больше чем его предок, соответственно левый сын всегда меньше чем его предок. Это значит что не надо обоих сыновей просматривать.
Насчёт предка я думал, но как то не стал реализовывать.
Ну насчёт просмотра сыновей.. в принципе это вопрос оптимизации, но всё равно спасибо.

Цитата:
Сообщение от Syuf
Легче проверять на равенство ключу не данный узел, а его потомков: тогда удаление в случае находки нужного потомка заключается в создании нового дерева с корнем в предке удаленного и всеми ответвлениями удаляемого узла и присоединении его к этому предку. Но вообще код серьезно недоработан.
А если нужно будет удалять корневой узел?
Насчёт доработки согласен))), но это потом.
И кстати я на dev c++ пишу так что в вижл цпп может хреново запускаться.
frmSm вне форума Ответить с цитированием
Старый 30.05.2010, 20:21   #9
Syuf
Форумчанин
 
Аватар для Syuf
 
Регистрация: 02.02.2010
Сообщений: 599
По умолчанию

Цитата:
И кстати я на dev c++ пишу так что в вижл цпп может хреново запускаться.
Хреново - это одно дело, а когда appItem и viewItem вообще не возвращают значения - это плохо.
Цитата:
А если нужно будет удалять корневой узел?
Чтобы удалить самый корневой узел, надо снести всё, иначе у любого другого есть свой предок.
"Лишь то читается легко, что написано с трудом; что в час написано, то в час и позабыто."
Syuf вне форума Ответить с цитированием
Старый 30.05.2010, 20:38   #10
frmSm
Пользователь
 
Регистрация: 30.05.2010
Сообщений: 12
По умолчанию

да с appItem и viewItem всё в порядке вроде.
appItem нужен для добавления в info (элемент-список узла или листа)
viewItem я использую для того чтобы пробежаться по info и вывести значения. Просто в info идёт добавление ещё одного элемента, если уже существует узел/лист с введённым ключём.
frmSm вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Узнать следующий узел в TTreeView RIO Общие вопросы Delphi 1 16.05.2010 02:59
Не получается удалить строки из TMemo RIO Общие вопросы Delphi 2 03.12.2009 01:07
Какой mac "видит" удаленный узел\роутер через NAT Zerone Свободное общение 3 05.10.2009 12:47
TreeView - необходимо развернуть нужный узел, независимо от степени вложенности Mikhail Bakurov Общие вопросы C/C++ 0 20.05.2009 07:42
Как выделить узел в TreeView inndim Общие вопросы Delphi 3 23.10.2008 13:32