Консультация № 183240
19.05.2011, 13:06
200.00 руб.
0 28 1
Здравствуйте, уважаемые эксперты! Прошу вас ответить на следующий вопрос:
Помогите с программой на С++. Под ОС Windows XP, Borland Builder 6 и Visual Studio 2005. Ответ нужен срочно .
Написать программу для работы по запросам оператора с упорядоченной таблицей,
реализованной в виде двоичного дерева поиска.

Ключ - целое число.Информация - строка произвольной длины.

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

В таблице могут храниться записи с одинаковыми ключами в одном узле дерева в виде списка информационных полей.

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


Примечания:
1.Программа должна содержать несколько функций;функция main должна выполнять: вывод меню, ввод и анализ ответа,вызов на исполнение требуемой функции;
2.В программе нужно предусмотреть проверку правильности ввода данных.
3.Оценить сложность реализованных алгоритмов.
4.(*) Для целей отладки реализовать форматированный вывод таблицы в виде дерева.
5.(*) Для целей отладки реализовать загрузку таблицы из файла в формате

- Ключ1
- Информация1
- Ключ2



Приложение:
похожая программа но тут

#include <iostream>

using namespace std;

typedef struct
{
char * key;
char * info;
void * pLeft;
void * pRight;
void * pParent;
} NODE;

typedef struct
{
NODE * pRoot;
} TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента,заданного своим ключом,без нарушения свойств упорядоченности таблицы
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в прямом порядке следования ключей,превышающих заданное значение ключа.если ключ не указан,то всей таблицы
"5. Find item by part of key", // поиск элемента соответствующего значению ключа совпадающего с заданным по первым N символам
"6. Get max difference", // вернуть максимальную разницу высот в дереве.
"7. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );
void FindByPartOfKey( TREE & tree );
void PrintMaxDifference( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );

NODE * CreateNode( char * key, char * info );
NODE * GetAt( TREE tree, char * key );
NODE * GetNodeWithNextKey( NODE * pNode );
void InsertAt( TREE & tree, NODE * pNode );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );

void PrintNodeByKeyCompare( NODE * pNode, char * key );
int keycmp( char * str1, char * str2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, FindByPartOfKey, PrintMaxDifference, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == 7 )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

// Функция добавления элемента.
void AddItem( TREE & tree )
{
NODE * pNode;
char key[256];
char info[256];
cout << "Please, enter the key: ";
cin >> key;
if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}
cout << "please, enter the information: ";
cin >> info;
pNode = CreateNode( key, info );
InsertAt( tree, pNode );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
char key[256];
NODE * pNode, * pParent, * pTemp, * pMin;
cout << "Please, enter the key: ";
cin >> key;
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}

if ( pNode->info )
delete [] pNode->info;
if ( pNode->key )
delete [] pNode->key;
delete [] pNode;
return;
}

pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot )
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
if ( pNode->info )
delete [] pNode->info;
if ( pNode->key )
delete [] pNode->key;
delete [] pNode;
return;
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
char key[256];
cout << "Please, enter the key: ";
cin >> key;
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout << "information: " << pNode->info << endl;
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{

NODE * pNode;

int ret;
do
{
cout << "View all tree - 1" << endl;
cout << "View all nodes after the key - 2" << endl;
ret = GetNum();
}while ( ret != 1 && ret != 2 );

if ( ret == 1 )
{
pNode = tree.pRoot;
if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << pNode->key << " ";
}
else
{
char key[256];
cout << "Please, enter the key: ";
cin >> key;
pNode = GetAt( tree, key );
if ( !pNode )
{
cout << "can not found element with the key = " << key << endl;
return;
}
}

while ( pNode = GetNodeWithNextKey( pNode ) )
cout << pNode->key << " ";
cout << endl;

cout << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// Функция выводит все найденные элементы, ключи которых частично совпадают с заданным.
void FindByPartOfKey( TREE & tree )
{
char key[256];
cout << "Please, enter the key: ";
cin >> key;
PrintNodeByKeyCompare( tree.pRoot, key );
cout << endl;
}

// Функция выводит максимальную разницу в уровнях между минимальным и максимальным элементами.
void PrintMaxDifference( TREE & tree )
{
NODE * pNode;
int level1 = 0, level2 = 0, delta;
pNode = tree.pRoot;
while ( pNode = ( NODE* ) pNode->pLeft )
level1++;
pNode = tree.pRoot;
while ( pNode = ( NODE* ) pNode->pRight )
level2++;
if ( level2 > level1 )
delta = level2 - level1;
else if ( level1 > level2 )
delta = level1 - level2;
else
delta = 0;
cout << "max difference is = " << delta << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "../load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
if ( GetAt( tree, key ) == NULL )
{
NODE * pNode = CreateNode( key, info );
InsertAt( tree, pNode );
info[0] = '\0';
key[0] = '\0';
}
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}

// Функция создания нового элемента.
NODE * CreateNode( char * key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );
if ( key )
{
pNode->key = new char[strlen( key )+1];
strcpy( pNode->key, key );
}
if ( info )
{
pNode->info = new char[strlen( info )+1];
strcpy( pNode->info, info );
}
return pNode;
}

// Функция возвращает указатель на элемент по его ключу.
NODE * GetAt( TREE tree, char * key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// Функция возвращает указатель на элемент со следующим по значению ключём.
NODE * GetNodeWithNextKey( NODE * pNode )
{
NODE * pNext;
pNode = ( NODE* ) pNode;
if ( pNode->pRight != NULL )
{
pNext = ( NODE* ) pNode->pRight;
while ( pNext->pLeft )
pNext = ( NODE* ) pNext->pLeft;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pRight == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, NODE * pNode )
{
NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = pNode;
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, pNode->key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
}
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
if ( pNode->key )
delete [] pNode->key;
if ( pNode->info )
delete [] pNode->info;
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// Функция отображения элементов со значениями ключей совпадающими с заданным ключём по первым N символам.
void PrintNodeByKeyCompare( NODE * pNode, char * key )
{
if ( pNode )
{
PrintNodeByKeyCompare( ( NODE* ) pNode->pRight, key );
if ( pNode->key == strstr( pNode->key, key ) )
cout << pNode->key << " ";
PrintNodeByKeyCompare( ( NODE* ) pNode->pLeft, key );
}
}

// Функция сравнения двух ключей в текстовом формате.
int keycmp( char * str1, char * str2 )
{
if ( str1 && str2 )
return atoi( str1 ) - atoi( str2 );
return 0;
}

Обсуждение

Неизвестный
19.05.2011, 13:12
общий
19.05.2011, 13:20
вот похожая программа, она работает.
- включение нового элемента в таблицу без нарушения свойств упорядоченности, если информация с заданным ключом уже есть,то выводится сообщение об ошибке;
- удаление из таблицы элемента,заданного своим ключом,без нарушения свойств упорядоченности таблицы;
- поиск информации по заданному ключу;
- вывод всего содержимого таблицы в прямом порядке следования ключей,превышающих заданное значение ключа.если ключ не указан,то всей таблицы;
- поиск элемента соответствующего значению ключа совпадающего с заданным по первым N символам(выводятся все элементы удовлетворяющие условию);
- вернуть максимальную разницу высот в дереве.

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

[code h=200]


#include <iostream>

using namespace std;

typedef struct
{
char * key;
char * info;
void * pLeft;
void * pRight;
void * pParent;
} NODE;

typedef struct
{
NODE * pRoot;
} TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента,заданного своим ключом,без нарушения свойств упорядоченности таблицы
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в прямом порядке следования ключей,превышающих заданное значение ключа.если ключ не указан,то всей таблицы
"5. Find item by part of key", // поиск элемента соответствующего значению ключа совпадающего с заданным по первым N символам
"6. Get max difference", // вернуть максимальную разницу высот в дереве.
"7. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );
void FindByPartOfKey( TREE & tree );
void PrintMaxDifference( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );

NODE * CreateNode( char * key, char * info );
NODE * GetAt( TREE tree, char * key );
NODE * GetNodeWithNextKey( NODE * pNode );
void InsertAt( TREE & tree, NODE * pNode );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );

void PrintNodeByKeyCompare( NODE * pNode, char * key );
int keycmp( char * str1, char * str2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, FindByPartOfKey, PrintMaxDifference, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == 7 )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

// Функция добавления элемента.
void AddItem( TREE & tree )
{
NODE * pNode;
char key[256];
char info[256];
cout << "Please, enter the key: ";
cin >> key;
if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}
cout << "please, enter the information: ";
cin >> info;
pNode = CreateNode( key, info );
InsertAt( tree, pNode );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
char key[256];
NODE * pNode, * pParent, * pTemp, * pMin;
cout << "Please, enter the key: ";
cin >> key;
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}

if ( pNode->info )
delete [] pNode->info;
if ( pNode->key )
delete [] pNode->key;
delete [] pNode;
return;
}

pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot )
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
if ( pNode->info )
delete [] pNode->info;
if ( pNode->key )
delete [] pNode->key;
delete [] pNode;
return;
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
char key[256];
cout << "Please, enter the key: ";
cin >> key;
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout << "information: " << pNode->info << endl;
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{

NODE * pNode;

int ret;
do
{
cout << "View all tree - 1" << endl;
cout << "View all nodes after the key - 2" << endl;
ret = GetNum();
}while ( ret != 1 && ret != 2 );

if ( ret == 1 )
{
pNode = tree.pRoot;
if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << pNode->key << " ";
}
else
{
char key[256];
cout << "Please, enter the key: ";
cin >> key;
pNode = GetAt( tree, key );
if ( !pNode )
{
cout << "can not found element with the key = " << key << endl;
return;
}
}

while ( pNode = GetNodeWithNextKey( pNode ) )
cout << pNode->key << " ";
cout << endl;

cout << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// Функция выводит все найденные элементы, ключи которых частично совпадают с заданным.
void FindByPartOfKey( TREE & tree )
{
char key[256];
cout << "Please, enter the key: ";
cin >> key;
PrintNodeByKeyCompare( tree.pRoot, key );
cout << endl;
}

// Функция выводит максимальную разницу в уровнях между минимальным и максимальным элементами.
void PrintMaxDifference( TREE & tree )
{
NODE * pNode;
int level1 = 0, level2 = 0, delta;
pNode = tree.pRoot;
while ( pNode = ( NODE* ) pNode->pLeft )
level1++;
pNode = tree.pRoot;
while ( pNode = ( NODE* ) pNode->pRight )
level2++;
if ( level2 > level1 )
delta = level2 - level1;
else if ( level1 > level2 )
delta = level1 - level2;
else
delta = 0;
cout << "max difference is = " << delta << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "../load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
if ( GetAt( tree, key ) == NULL )
{
NODE * pNode = CreateNode( key, info );
InsertAt( tree, pNode );
info[0] = '\0';
key[0] = '\0';
}
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}

// Функция создания нового элемента.
NODE * CreateNode( char * key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );
if ( key )
{
pNode->key = new char[strlen( key )+1];
strcpy( pNode->key, key );
}
if ( info )
{
pNode->info = new char[strlen( info )+1];
strcpy( pNode->info, info );
}
return pNode;
}

// Функция возвращает указатель на элемент по его ключу.
NODE * GetAt( TREE tree, char * key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// Функция возвращает указатель на элемент со следующим по значению ключём.
NODE * GetNodeWithNextKey( NODE * pNode )
{
NODE * pNext;
pNode = ( NODE* ) pNode;
if ( pNode->pRight != NULL )
{
pNext = ( NODE* ) pNode->pRight;
while ( pNext->pLeft )
pNext = ( NODE* ) pNext->pLeft;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pRight == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, NODE * pNode )
{
NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = pNode;
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, pNode->key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
}
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
if ( pNode->key )
delete [] pNode->key;
if ( pNode->info )
delete [] pNode->info;
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// Функция отображения элементов со значениями ключей совпадающими с заданным ключём по первым N символам.
void PrintNodeByKeyCompare( NODE * pNode, char * key )
{
if ( pNode )
{
PrintNodeByKeyCompare( ( NODE* ) pNode->pRight, key );
if ( pNode->key == strstr( pNode->key, key ) )
cout << pNode->key << " ";
PrintNodeByKeyCompare( ( NODE* ) pNode->pLeft, key );
}
}

// Функция сравнения двух ключей в текстовом формате.
int keycmp( char * str1, char * str2 )
{
if ( str1 && str2 )
return atoi( str1 ) - atoi( str2 );
return 0;
}[/code]
Неизвестный
19.05.2011, 13:21
общий
По-моему, вот Ваше задание один к одному: вопрос 182777
Неизвестный
19.05.2011, 13:22
общий
А, нет, прошу прощения, там разница в условии.
Неизвестный
19.05.2011, 13:30
общий
Цитата: 24617
А, нет, прошу прощения, там разница в условии.

да, почти... я тоже сначала обрадовалась.
давно
Посетитель
7438
7205
19.05.2011, 15:45
общий
На когда Вам надо? Тем вопросом я занимался... Могу и Вам помочь.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 15:49
общий
19.05.2011, 15:50
Цитата: Лысков Игорь Витальевич
На когда Вам надо? Тем вопросом я занимался... Могу и Вам помочь.

ну вообще на сегодня до 7 часов.
можно и позже

я посмотрела у меня там попроще. не нужны никакие кольца а просто список информационных полей.
давно
Посетитель
7438
7205
19.05.2011, 15:51
общий
Вам как, подправить Вашу или ту, свою?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 15:52
общий
19.05.2011, 15:57
вот уже и с обходом в обратном порядке. и я пытаюсь сюда этот список сделать
[code h=200]#include <iostream>

using namespace std;

typedef struct {

char * data;
struct INF *nextPtr;
} INF;

typedef struct
{
int key;
INF * info;
void * pLeft;
void * pRight;
void * pParent;
} NODE;


typedef struct
{
NODE * pRoot;
} TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента, заданного своим ключом
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в обратном порядке следования ключей
"5. Find node with least key", // поиск элемента соответствтвующего значению наименьшего ключа
"6. Input tree from file", //загрузка дерева из файла
"7. Save tree to file", //сохранение дерева в файл
"8. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );

void PrintNodeWithLeastKey( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );
void Swap( TREE & tree );

NODE * CreateNode( int key, char * info );
NODE * GetAt( TREE tree, int key );
NODE * GetNodeWithPrevKey( NODE * pNode );
void InsertAt( TREE & tree, NODE * pNode );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );
int keycmp( int key1, int key2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, PrintNodeWithLeastKey, Init, Swap, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == 8 )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

void AddItem( TREE & tree )
{
NODE * pNode;
char info[256];
int key;

cout << "Please, enter the key: ";
key = GetNum();

/*if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}*/
cout << "please, enter the information: ";
cin >> info;
pNode = CreateNode( key, info );
InsertAt( tree, pNode );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
int key;
NODE * pNode, * pParent, * pTemp, * pMin;
cout << "Please, enter the key: ";

key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}

if ( pNode->info->data )
delete [] pNode->info->data ;
delete [] pNode;
return;
}

pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot )
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
if ( pNode->info->data )
delete [] pNode->info->data ;
delete [] pNode;
return;
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
int key;

cout << "Please, enter the key: ";
key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout << "information: " << pNode->info->data << endl;
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{
NODE * pNode = tree.pRoot;

if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}

while ( pNode->pRight )
pNode = ( NODE* ) pNode->pRight;
cout << pNode->key << " ";

while ( pNode = GetNodeWithPrevKey( pNode ) )
cout << pNode->key << " ";
cout << endl;

cout << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// функция отображения элемента с минимальным ключём
void PrintNodeWithLeastKey( TREE & tree )
{
NODE * pNode = tree.pRoot;
if ( !pNode )
{
cout << "tree is empty" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << "the least node is: " << pNode->key << endl;
cout<< "information: " << pNode->info->data << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
//Swap( tree );
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "../load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
if ( GetAt( tree, atoi( key ) ) == NULL )
{
NODE * pNode = CreateNode( atoi( key ), info );
InsertAt( tree, pNode );
info[0] = '\0';
key[0] = '\0';
}
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}


// функция создания нового элемента
NODE * CreateNode( int key, char * info )
{
NODE * pNode;
INF * newPtr;
INF * prevPtr;
INF * curPtr;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );

pNode->key = key;

if ( info )
{
pNode->info->data = new char[strlen( info )+1];
strcpy( pNode->info->data, info );
}
return pNode;
}

// функция возвращает элемент по его ключу
NODE * GetAt( TREE tree, int key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// функция возвращает элемент предшестующий данному
NODE * GetNodeWithPrevKey( NODE * pNode )
{
NODE * pNext;
if ( !pNode )
return NULL;
if ( pNode->pLeft != NULL )
{
pNext = ( NODE* ) pNode->pLeft;
while ( pNext->pRight )
pNext = ( NODE* ) pNext->pRight;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pLeft == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, NODE * pNode )
{
NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = pNode;
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, pNode->key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
}
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
if (pNode->info->data )
delete []pNode->info->data ;
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// функция сравнения ключей
int keycmp( int key1, int key2 )
{
return key1 - key2;
}[/code]
давно
Посетитель
7438
7205
19.05.2011, 15:53
общий
просто список информационных полей
Так было в первой версии
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
19.05.2011, 15:56
общий
Ок, сделаем за сегодня.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 15:59
общий
лучше мою подправить)) в ней я уже разбираюсь более менее))
Неизвестный
19.05.2011, 16:04
общий
19.05.2011, 16:07
вот такая же как у меня ток тут ключи не могли повторяться. она без списка.
и удаление здесь сразу элемента полностью.

[code h=200]#include <iostream>

using namespace std;

typedef struct
{
int key;
char * info;
void * pLeft;
void * pRight;
void * pParent;
} NODE;

typedef struct
{
NODE * pRoot;
} TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента, заданного своим ключом
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в обратном порядке следования ключей
"5. Find node with least key", // поиск элемента соответствтвующего значению наименьшего ключа
"6. Input tree from file", //загрузка дерева из файла
"7. Save tree to file", //сохранение дерева в файл
"8. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );

void PrintNodeWithLeastKey( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );
void Swap( TREE & tree );

NODE * CreateNode( int key, char * info );
NODE * GetAt( TREE tree, int key );
NODE * GetNodeWithPrevKey( NODE * pNode );
void InsertAt( TREE & tree, NODE * pNode );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );
int keycmp( int key1, int key2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, PrintNodeWithLeastKey, Init, Swap, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == 8 )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

void AddItem( TREE & tree )
{
NODE * pNode;
char info[256];
int key;

cout << "Please, enter the key: ";
key = GetNum();

if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}
cout << "please, enter the information: ";
cin >> info;
pNode = CreateNode( key, info );
InsertAt( tree, pNode );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
int key;
NODE * pNode, * pParent, * pTemp, * pMin;
cout << "Please, enter the key: ";

key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}

if ( pNode->info )
delete [] pNode->info;
delete [] pNode;
return;
}

pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot )
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
if ( pNode->info )
delete [] pNode->info;
delete [] pNode;
return;
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
int key;

cout << "Please, enter the key: ";
key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout << "information: " << pNode->info << endl;
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{
NODE * pNode = tree.pRoot;

if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}

while ( pNode->pRight )
pNode = ( NODE* ) pNode->pRight;
cout << pNode->key << " ";

while ( pNode = GetNodeWithPrevKey( pNode ) )
cout << pNode->key << " ";
cout << endl;

cout << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// функция отображения элемента с минимальным ключём
void PrintNodeWithLeastKey( TREE & tree )
{
NODE * pNode = tree.pRoot;
if ( !pNode )
{
cout << "tree is empty" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << "the least node is: " << pNode->key << endl;
cout<< "information: " << pNode->info << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
//Swap( tree );
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "../load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
if ( GetAt( tree, atoi( key ) ) == NULL )
{
NODE * pNode = CreateNode( atoi( key ), info );
InsertAt( tree, pNode );
info[0] = '\0';
key[0] = '\0';
}
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}



// функция создания нового элемента
NODE * CreateNode( int key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );

pNode->key = key;

if ( info )
{
pNode->info = new char[strlen( info )+1];
strcpy( pNode->info, info );
}
return pNode;
}

// функция возвращает элемент по его ключу
NODE * GetAt( TREE tree, int key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// функция возвращает элемент предшестующий данному
NODE * GetNodeWithPrevKey( NODE * pNode )
{
NODE * pNext;
if ( !pNode )
return NULL;
if ( pNode->pLeft != NULL )
{
pNext = ( NODE* ) pNode->pLeft;
while ( pNext->pRight )
pNext = ( NODE* ) pNext->pRight;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pLeft == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, NODE * pNode )
{
NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = pNode;
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, pNode->key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
}
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
if ( pNode->info )
delete [] pNode->info;
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// функция сравнения ключей
int keycmp( int key1, int key2 )
{
return key1 - key2;
}[/code]
давно
Посетитель
7438
7205
19.05.2011, 16:06
общий
лучше мою подправить
Хорошо
До которого часа (МСК) Вы бы хотели получить программу?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 16:10
общий
Цитата: Лысков Игорь Витальевич
Хорошо
До которого часа (МСК) Вы бы хотели получить программу?


до 19-00 по мск ))) хватит времени? смогу потянуть ещё минут 30 если что.
давно
Посетитель
7438
7205
19.05.2011, 16:24
общий
Я смотрю, там у Вас еще отсутствует функция Swap для записи на диск.
Она нужна?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 16:34
общий
не нужна. у меня только загрузка с файла
давно
Посетитель
7438
7205
19.05.2011, 17:24
общий
это ответ
Здравствуйте, Tigresska!
Вот Вам подправленная программа

[code h=200]#include <iostream>

using namespace std;

typedef struct INF
{

char * data;
struct INF *nextPtr;
}INF;

typedef struct NODE
{
int key;
INF * info;
NODE * pLeft;
NODE * pRight;
NODE * pParent;
}NODE;


typedef struct TREE
{
NODE * pRoot;
}TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента, заданного своим ключом
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в обратном порядке следования ключей
"5. Find node with least key", // поиск элемента соответствтвующего значению наименьшего ключа
"6. Input tree from file", //загрузка дерева из файла
"7. Output tree to file", //выгрузка дерева в файл
"8. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );

void PrintNodeWithLeastKey( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );
void Write( TREE & tree );

NODE * CreateNode( int key, char * info );
NODE * GetAt( TREE tree, int key );
NODE * GetNodeWithPrevKey( NODE * pNode );
void InsertAt( TREE & tree, int key, char * info );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );
int keycmp( int key1, int key2 );

void ( *func[] )( TREE & ) =
{ NULL, AddItem, RemoveItem, FindAt, View, PrintNodeWithLeastKey, Init, Write, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == MesCount )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

void AddItem( TREE & tree )
{
char info[256];
int key;

cout << "Please, enter the key: ";
key = GetNum();

/*if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}*/
cout << "please, enter the information: ";
cin >> info;
InsertAt( tree, key, info );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
int key, iInf, i;
NODE * pNode, * pParent, * pTemp, * pMin;
INF * pInf, * pNextInf, * pPrevInf;
cout << "Please, enter the key: ";

key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

if (pNode->info->nextPtr)
{
cout << "Please, enter key number: ";
iInf = GetNum();
}
else
iInf = 0;

if ((iInf == 0) || (pNode->info->nextPtr == NULL))
{
pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}
}
else
{
pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot)
if (pNode->info->nextPtr==NULL)
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
}
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
else
{
for (pPrevInf=NULL,pInf=pNode->info,i=1;pInf && (i!=iInf);
i++,pPrevInf=pInf,pInf=pInf->nextPtr);
if ((i==iInf) && pInf)
{
if (pPrevInf==NULL)
pNode->info = pInf->nextPtr;
else
pPrevInf->nextPtr = pInf->nextPtr;
delete [] pInf->data;
delete pInf;
}
}
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
INF * pInf;
int key;

cout << "Please, enter the key: ";
key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

void ViewKey( NODE * pNode)
{
INF * pInf;

cout << pNode->key << "(";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
{
cout << pInf->data;
if (pInf->nextPtr)
cout << ",";
else
cout << ") ";
}
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{
NODE * pNode = tree.pRoot;

if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}

while ( pNode->pRight )
pNode = ( NODE* ) pNode->pRight;

ViewKey(pNode);

while ( pNode = GetNodeWithPrevKey( pNode ) )
ViewKey(pNode);

cout << endl << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// функция отображения элемента с минимальным ключём
void PrintNodeWithLeastKey( TREE & tree )
{
INF * pInf;
NODE * pNode = tree.pRoot;
if ( !pNode )
{
cout << "tree is empty" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << "the least node is: " << pNode->key << endl;
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
//Swap( tree );
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "./load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
InsertAt( tree, atoi( key ), info );
info[0] = '\0';
key[0] = '\0';
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}

void WriteNode(FILE *pFile, NODE * pNode)
{
INF * pInf;
char key[32];

for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
fprintf(pFile, "%d\n%s\n", pNode->key, pInf->data);
if (pNode->pLeft)
WriteNode(pFile, pNode->pLeft);
if (pNode->pRight)
WriteNode(pFile, pNode->pRight);
}

// Функция записи дерева в файл "load.txt".
void Write( TREE & tree )
{
NODE * pNode = tree.pRoot;

FILE * pFile = fopen( "./load.txt", "w" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
if ( !pNode )
{
cout << "tree is empty" << endl;
}
else
WriteNode(pFile, pNode);
cout << "writing to file complete" << endl;
fclose( pFile );
}

// функция создания нового элемента
NODE * CreateNode( int key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );

pNode->key = key;

if ( info )
{
pNode->info = new INF;
pNode->info->data = new char[strlen( info )+1];
strcpy( pNode->info->data, info );
pNode->info->nextPtr = NULL;
}
return pNode;
}

// функция возвращает элемент по его ключу
NODE * GetAt( TREE tree, int key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// функция возвращает элемент предшестующий данному
NODE * GetNodeWithPrevKey( NODE * pNode )
{
NODE * pNext;
if ( !pNode )
return NULL;
if ( pNode->pLeft != NULL )
{
pNext = ( NODE* ) pNode->pLeft;
while ( pNext->pRight )
pNext = ( NODE* ) pNext->pRight;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pLeft == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, int key, char * info )
{
NODE *pNode;
INF *pInf, *pPrevInf;

NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = CreateNode( key, info );
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
else
{
for (pInf=pTemp->info; pInf; pPrevInf=pInf,pInf=pInf->nextPtr);
pInf = new INF;
pPrevInf->nextPtr = pInf;
pInf->data = new char[strlen( info )+1];
strcpy( pInf->data, info );
pInf->nextPtr = NULL;
return;
}
}
pNode = CreateNode( key, info );
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = pNode;
else
pPrev->pLeft = pNode;
pNode->pParent = pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
INF *pInf, *pNextInf;
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// функция сравнения ключей
int keycmp( int key1, int key2 )
{
return key1 - key2;
}
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
19.05.2011, 17:29
общий
19.05.2011, 17:30
Сделал работу с полем info, как со списком.
1) при добавлении ключа, равного имеющемуся, добавляем только info
2) учел при выводе поля info, при удалении...
3) по мелочи ретушь...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 17:33
общий
19.05.2011, 17:34
Спасибо.))
только вот
удаление из таблицы элемента,заданного своим ключом,без нарушения свойств упорядоченности таблицы(если элементов несколько, то указывается номер удаляемого элемента);
а у вас удаляет весь элемент полностью.

и там вывод всего содержимого . т.е. с информацией . можно сделать чтоб не только ключи выводила ? там где просто в строку
Неизвестный
19.05.2011, 18:54
общий
удаление обязательно нужно исправить. препод заметит и не засчитает.
давно
Посетитель
7438
7205
19.05.2011, 19:33
общий
Еще чуть подождете?
Чего-то глюки повылазили...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 19:45
общий
19.05.2011, 20:08
Адресаты:
подожду конечно... смысла сдавать нет пока не работает. не примут((
и можно подправить вывод, а то дерево какое то получилось непонятное.
и выгрузка в файл всетаки нужна была
давно
Посетитель
7438
7205
19.05.2011, 20:38
общий
Гляньте...
[code h=200]#include <iostream>

using namespace std;

typedef struct INF
{

char * data;
struct INF *nextPtr;
}INF;

typedef struct NODE
{
int key;
INF * info;
void * pLeft;
void * pRight;
void * pParent;
}NODE;


typedef struct TREE
{
NODE * pRoot;
}TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента, заданного своим ключом
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в обратном порядке следования ключей
"5. Find node with least key", // поиск элемента соответствтвующего значению наименьшего ключа
"6. Input tree from file", //загрузка дерева из файла
"7. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );

void PrintNodeWithLeastKey( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );

NODE * CreateNode( int key, char * info );
NODE * GetAt( TREE tree, int key );
NODE * GetNodeWithPrevKey( NODE * pNode );
void InsertAt( TREE & tree, int key, char * info );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );
int keycmp( int key1, int key2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, PrintNodeWithLeastKey, Init, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == MesCount )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

void AddItem( TREE & tree )
{
char info[256];
int key;

cout << "Please, enter the key: ";
key = GetNum();

/*if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}*/
cout << "please, enter the information: ";
cin >> info;
InsertAt( tree, key, info );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
int key, iInf, i;
NODE * pNode, * pParent, * pTemp, * pMin;
INF * pInf, * pNextInf, * pPrevInf, **ppInf;
cout << "Please, enter the key: ";

key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

if (pNode->info->nextPtr)
{
cout << "Please, enter key number: ";
iInf = GetNum();
}
else
iInf = 0;

pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}

if (iInf == 0)
{
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
else
{
i = 1;
ppInf = &pNode->info;
do
{
if (i==iInf)
break;
ppInf = &((*ppInf)->nextPtr);
i++;
}while (*ppInf);

if (*ppInf && (i==iInf))
{
pInf = (*ppInf);
do
{
*ppInf = (*ppInf)->nextPtr;
}while (*ppInf);
delete [] pInf->data;
delete pInf;
}
}
return;
}

pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot)
if (pNode->info->nextPtr==NULL)
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}

if (iInf == 0)
{
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
else
{
i = 1;
ppInf = &pNode->info;
do
{
if (i==iInf)
break;
ppInf = &((*ppInf)->nextPtr);
i++;
}while (*ppInf);

if (*ppInf && (i==iInf))
{
pInf = (*ppInf);
do
{
*ppInf = (*ppInf)->nextPtr;
}while ((*ppInf)->nextPtr);
delete [] pInf->data;
delete pInf;
}
}
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
INF * pInf;
int key;

cout << "Please, enter the key: ";
key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{
NODE * pNode = tree.pRoot;

if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}

while ( pNode->pRight )
pNode = ( NODE* ) pNode->pRight;
cout << pNode->key << " ";

while ( pNode = GetNodeWithPrevKey( pNode ) )
cout << pNode->key << " ";
cout << endl;

cout << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// функция отображения элемента с минимальным ключём
void PrintNodeWithLeastKey( TREE & tree )
{
INF * pInf;
NODE * pNode = tree.pRoot;
if ( !pNode )
{
cout << "tree is empty" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << "the least node is: " << pNode->key << endl;
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
//Swap( tree );
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "../load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
if ( GetAt( tree, atoi( key ) ) == NULL )
{
InsertAt( tree, atoi( key ), info );
info[0] = '\0';
key[0] = '\0';
}
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}


// функция создания нового элемента
NODE * CreateNode( int key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );

pNode->key = key;

if ( info )
{
pNode->info = new INF;
pNode->info->data = new char[strlen( info )+1];
strcpy( pNode->info->data, info );
pNode->info->nextPtr = NULL;
}
return pNode;
}

// функция возвращает элемент по его ключу
NODE * GetAt( TREE tree, int key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// функция возвращает элемент предшестующий данному
NODE * GetNodeWithPrevKey( NODE * pNode )
{
NODE * pNext;
if ( !pNode )
return NULL;
if ( pNode->pLeft != NULL )
{
pNext = ( NODE* ) pNode->pLeft;
while ( pNext->pRight )
pNext = ( NODE* ) pNext->pRight;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pLeft == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, int key, char * info )
{
NODE *pNode;
INF *pInf, *pPrevInf;

NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = CreateNode( key, info );
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
else
{
for (pInf=pTemp->info; pInf; pPrevInf=pInf,pInf=pInf->nextPtr);
pInf = new INF;
pPrevInf->nextPtr = pInf;
pInf->data = new char[strlen( info )+1];
strcpy( pInf->data, info );
pInf->nextPtr = NULL;
return;
}
}
pNode = CreateNode( key, info );
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
INF *pInf, *pNextInf;
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// функция сравнения ключей
int keycmp( int key1, int key2 )
{
return key1 - key2;
}
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
19.05.2011, 20:56
общий
19.05.2011, 21:03
Ошибки...
Позвольте я немного прервусь. Взбодрю мозги. Чуть позже исправлю...
Чего-то я зациклился в спешке...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
19.05.2011, 21:00
общий
Кстати, что значит "подправить вывод"? Как именно?
Выгрузку я тоже добавлю, как и вывод с полями...
К полночи все будет... Хорошо?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
19.05.2011, 21:03
общий
всеравно удаляет элемент полностью.
если у нас например эл 3 с информацией www и с информацией rrr
выбираю удалить первы или второй. т.е. информацию. а он удаляет полностью все связаное с 3
давно
Посетитель
7438
7205
20.05.2011, 00:53
общий
Вот, удаление исправил. В п/п View добавил вывод поля info (в скобках, через запятую).
При удалении в случае одинаковых ключей спрашивается номер по порядку (1,2,...) Ввод 0 удалит все.

Осталось добавить запись в файл. Кстати, почему файл в родительском каталоге? Лучше в текущем...

[code h=200]#include <iostream>

using namespace std;

typedef struct INF
{

char * data;
struct INF *nextPtr;
}INF;

typedef struct NODE
{
int key;
INF * info;
void * pLeft;
void * pRight;
void * pParent;
}NODE;


typedef struct TREE
{
NODE * pRoot;
}TREE;

char * message[] = { "1. Add new item", // включение нового элемента в таблицу без нарушения свойств упорядоченности
"2. Remove item", // удаление из таблицы элемента, заданного своим ключом
"3. Find item by key", // поиск информации по заданному ключу
"4. View", // вывод всего содержимого таблицы в обратном порядке следования ключей
"5. Find node with least key", // поиск элемента соответствтвующего значению наименьшего ключа
"6. Input tree from file", //загрузка дерева из файла
"7. Exit" }; // выход

int MesCount = sizeof( message ) / sizeof( message[0] );

void AddItem( TREE & tree );
void RemoveItem( TREE & tree );
void FindAt( TREE & tree );
void View( TREE & tree );

void PrintNodeWithLeastKey( TREE & tree );
void Exit( TREE & tree );

int ViewMenu();
int GetNum();

void Init( TREE & tree );

NODE * CreateNode( int key, char * info );
NODE * GetAt( TREE tree, int key );
NODE * GetNodeWithPrevKey( NODE * pNode );
void InsertAt( TREE & tree, int key, char * info );
void ReleaseNode( NODE * pNode );
void PrintNode( NODE * pNode, int offset );
int keycmp( int key1, int key2 );

void ( *func[] )( TREE & ) = { NULL, AddItem, RemoveItem, FindAt, View, PrintNodeWithLeastKey, Init, Exit };

int main()
{
TREE tree;
int ret;

Init( tree );

do
{
ret = ViewMenu();
func[ret]( tree );
if ( ret == MesCount )
break;
}
while ( ret );

return 0;
}

int ViewMenu()
{
int ret;
do
{
cout << "_________________________" << endl;
cout << endl << "Please, select:\n";
for ( int i = 0; i < MesCount; i++ )
cout << message[i] << endl;
cout << "_________________________" << endl;
ret = GetNum();
}
while ( ret < 1 || ret > MesCount );
return ret;
}

int GetNum()
{
int a;
cin >> a;
while ( !( cin.good() || cin.eof() ) || ( a < 0 ) )
{
cout << "Wrong value!" << endl;
cin.clear();
cin.ignore();
cin >> a;
}
return a;
}

void AddItem( TREE & tree )
{
char info[256];
int key;

cout << "Please, enter the key: ";
key = GetNum();

/*if ( GetAt( tree, key ) )
{
cout << "Error: Key collision!" << endl;
return;
}*/
cout << "please, enter the information: ";
cin >> info;
InsertAt( tree, key, info );
}

// Функция удаления элементам по его ключу.
void RemoveItem( TREE & tree )
{
int key, iInf, i;
NODE * pNode, * pParent, * pTemp, * pMin;
INF * pInf, * pNextInf, * pPrevInf;
cout << "Please, enter the key: ";

key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}

if (pNode->info->nextPtr)
{
cout << "Please, enter key number: ";
iInf = GetNum();
}
else
iInf = 0;

if ((iInf == 0) || (pNode->info->nextPtr == NULL))
{
pParent = ( NODE* ) pNode->pParent;
pTemp = NULL;

if ( !pNode->pLeft )
pTemp = ( NODE* ) pNode->pRight;
else if ( !pNode->pRight )
pTemp = ( NODE* ) pNode->pLeft;

if ( pTemp )
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pTemp;
pTemp->pParent = pParent;
}
else if ( pParent->pRight == pNode )
{
pParent->pRight = pTemp;
pTemp->pParent = pParent;
}
}
else if ( pNode == tree.pRoot )
{
tree.pRoot = pTemp;
pTemp->pParent = NULL;
}
}
else
{
pMin = ( NODE* ) pNode->pRight;
if ( pMin )
{
while ( pMin->pLeft )
pMin = ( NODE* ) pMin->pLeft;

pMin->pLeft = ( NODE* ) pNode->pLeft;
( ( NODE* ) pNode->pLeft )->pParent = pMin;

pTemp = ( NODE* ) pMin->pParent;

if ( pTemp != pNode )
{
if ( pTemp->pLeft == pMin )
{
pTemp->pLeft = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
else
{
pTemp->pRight = pMin->pRight;
if ( pMin->pRight )
( ( NODE* ) pMin->pRight )->pParent = pTemp;
}
pMin->pRight = pNode->pRight;
( ( NODE* ) pNode->pRight )->pParent = pMin;
}
if ( pParent )
{
if ( pParent->pLeft == pNode )
{
pParent->pLeft = pMin;
pMin->pParent = pParent;
}
else
{
pParent->pRight = pMin;
pMin->pParent = pParent;
}
}
}
else
{
pParent = ( NODE* ) pNode->pParent;
if ( pParent )
{
if ( pParent->pRight == pNode )
pParent->pRight = NULL;
else
pParent->pLeft = NULL;
}
}
if ( pNode == tree.pRoot)
if (pNode->info->nextPtr==NULL)
{
tree.pRoot = pMin;
if ( pMin )
pMin->pParent = NULL;
}
}
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
else
{
for (pPrevInf=NULL,pInf=pNode->info,i=1;pInf && (i!=iInf);
i++,pPrevInf=pInf,pInf=pInf->nextPtr);
if ((i==iInf) && pInf)
{
if (pPrevInf==NULL)
pNode->info = pInf->nextPtr;
else
pPrevInf->nextPtr = pInf->nextPtr;
delete [] pInf->data;
delete pInf;
}
}
}

// Функция вывода элемента по его ключу.
void FindAt( TREE & tree )
{
NODE * pNode;
INF * pInf;
int key;

cout << "Please, enter the key: ";
key = GetNum();
if ( ( pNode = GetAt( tree, key ) ) == NULL )
{
cout << "can not found element with the key = " << key << endl;
return;
}
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

void ViewKey( NODE * pNode)
{
INF * pInf;

cout << pNode->key << "(";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
{
cout << pInf->data;
if (pInf->nextPtr)
cout << ",";
else
cout << ") ";
}
}

// Функция отображения всех элементов дерева.
void View( TREE & tree )
{
NODE * pNode = tree.pRoot;

if ( !pNode )
{
cout << endl << "Tree is empty!" << endl;
return;
}

while ( pNode->pRight )
pNode = ( NODE* ) pNode->pRight;

ViewKey(pNode);

while ( pNode = GetNodeWithPrevKey( pNode ) )
ViewKey(pNode);

cout << endl << endl << endl;

int offset = 0;
PrintNode( tree.pRoot, offset );
cout << endl;
}

// функция отображения элемента с минимальным ключём
void PrintNodeWithLeastKey( TREE & tree )
{
INF * pInf;
NODE * pNode = tree.pRoot;
if ( !pNode )
{
cout << "tree is empty" << endl;
return;
}
while ( pNode->pLeft )
pNode = ( NODE* ) pNode->pLeft;
cout << "the least node is: " << pNode->key << endl;
cout<< "information: ";
for (pInf=pNode->info; pInf; pInf=pInf->nextPtr)
cout << pInf->data << " ";
cout << endl;
}

// Выход из программы.
void Exit( TREE & tree )
{
//Swap( tree );
ReleaseNode( tree.pRoot );
}

// Функция загрузки дерева из файла "load.txt".
void Init( TREE & tree )
{
char str[256], key[256], info[256];

memset( &tree, 0x00, sizeof( TREE ) );
FILE * pFile = fopen( "./load.txt", "r" );
if ( !pFile )
{
cout << "can not open file!" << endl;
return;
}
for ( int cntr = 1; fscanf( pFile, "%s", str ) != -1; cntr++ )
{
if ( cntr % 2 != 0 )
strcpy( key, str );
else
strcpy( info, str );

if ( strlen( key ) && strlen( info ) && cntr > 1 )
{
InsertAt( tree, atoi( key ), info );
info[0] = '\0';
key[0] = '\0';
}
}
cout << "loading from file complete" << endl;
fclose( pFile );
}


// функция создания нового элемента
NODE * CreateNode( int key, char * info )
{
NODE * pNode;

pNode = ( NODE* ) new NODE;
memset( pNode, 0x00, sizeof( NODE ) );

pNode->key = key;

if ( info )
{
pNode->info = new INF;
pNode->info->data = new char[strlen( info )+1];
strcpy( pNode->info->data, info );
pNode->info->nextPtr = NULL;
}
return pNode;
}

// функция возвращает элемент по его ключу
NODE * GetAt( TREE tree, int key )
{
if ( !tree.pRoot )
return NULL;
NODE * pNode = tree.pRoot;
while ( pNode )
{
int res = keycmp( pNode->key, key );
if ( res < 0 )
pNode = ( NODE* ) pNode->pRight;
else if ( !res )
return pNode;
else
pNode = ( NODE* ) pNode->pLeft;
}
return NULL;
}

// функция возвращает элемент предшестующий данному
NODE * GetNodeWithPrevKey( NODE * pNode )
{
NODE * pNext;
if ( !pNode )
return NULL;
if ( pNode->pLeft != NULL )
{
pNext = ( NODE* ) pNode->pLeft;
while ( pNext->pRight )
pNext = ( NODE* ) pNext->pRight;
return pNext;
}
pNext = ( NODE* ) pNode->pParent;
while ( pNext && pNext->pLeft == pNode )
{
pNode = pNext;
pNext = ( NODE* ) pNode->pParent;
}
return pNext;
}

// Функция добавления нового элемента.
void InsertAt( TREE & tree, int key, char * info )
{
NODE *pNode;
INF *pInf, *pPrevInf;

NODE * pTemp, * pPrev;
if ( !tree.pRoot )
{
tree.pRoot = CreateNode( key, info );
return;
}
pTemp = tree.pRoot;
while ( pTemp )
{
pPrev = pTemp;
int res = keycmp( pTemp->key, key );
if ( res < 0 )
pTemp = ( NODE* ) pTemp->pRight;
else if ( res > 0 )
pTemp = ( NODE* ) pTemp->pLeft;
else
{
for (pInf=pTemp->info; pInf; pPrevInf=pInf,pInf=pInf->nextPtr);
pInf = new INF;
pPrevInf->nextPtr = pInf;
pInf->data = new char[strlen( info )+1];
strcpy( pInf->data, info );
pInf->nextPtr = NULL;
return;
}
}
pNode = CreateNode( key, info );
int res = keycmp( pPrev->key, pNode->key );
if ( res < 0 )
pPrev->pRight = ( void* ) pNode;
else
pPrev->pLeft = ( void* ) pNode;
pNode->pParent = ( void* ) pPrev;
}

// Функция освобождения динамической памяти, занятой элементом и всему дочерними элементами.
void ReleaseNode( NODE * pNode )
{
INF *pInf, *pNextInf;
if ( pNode )
{
if ( pNode->pRight )
ReleaseNode( ( NODE* ) pNode->pRight );
if ( pNode->pLeft )
ReleaseNode( ( NODE* ) pNode->pLeft );
for (pInf=pNode->info; pInf; pInf=pNextInf)
{
pNextInf = pInf->nextPtr;
delete []pInf->data ;
delete pInf;
}
delete [] pNode;
}
}

// Рекурсивная функция печати элемента и всех его дочерних элементов.
void PrintNode( NODE * pNode, int offset )
{
if ( pNode )
{
PrintNode( ( NODE* ) pNode->pRight, offset + 1 );
for ( int i = 0; i < offset; i++ )
cout << " ";
cout << pNode->key << endl;
PrintNode( ( NODE* ) pNode->pLeft, offset + 1 );
}
}

// функция сравнения ключей
int keycmp( int key1, int key2 )
{
return key1 - key2;
}
[/code]
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
7438
7205
20.05.2011, 01:35
общий
Все! Заменил в ответе.
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа