Понедельник, 29.06.2026
Шпаргалка :)
Меню сайта
Категории раздела
Мои статьи [172]
Наш опрос
Оцените мой сайт
Всего ответов: 259
Форма входа
Главная » Статьи » Мои статьи

деревья
struct Node {
int Key;
Node *Left, *Right;
};

typedef Node *PNode;


int data[] = { 21, 8, 9, 11, 15, 19, 20, 21, 7 };
PNode Tree;
n = sizeof(data) / sizeof(int) - 1;
Tree = MakeTree (data, 0, n);


PNode MakeTree (int data[], int &from, int n)
{
PNode Tree;
int n1, n2;
if ( n == 0 ) return NULL;
Tree = new Node;
Tree->Key = data[from++];
n1 = n / 2;
n2 = n - n1 - 1;
Tree->Left = MakeTree(data, from, n1);
Tree->Right = MakeTree(data, from, n2);
return Tree;
}

Для примера ниже дана рекурсивная процедура просмотра дерева слева направо. Обратите
внимание, что поскольку дерево является рекурсивной структурой данных, при работе с ним
естественно широко применять рекурсию.
void PrintLKP(PNode Tree)
{
if ( ! Tree ) return;
PrintLKP(Tree->Left);
printf("%d ", Tree->Key);
PrintLKP(Tree->Right);
}

сортировка

void AddToTree (PNode &Tree, int data)
{
if ( ! Tree ) {
Tree = new Node;
Tree->Key = data;
Tree-> Left = NULL;
Tree->Right = NULL;
return;
}
if ( data < Tree->Key )
AddToTree ( Tree->Left, data );
else AddToTree ( Tree->Right, data );
}

поиск

PNode Search (PNode Tree, int what)
{
if ( ! Tree ) return NULL;
if ( what == Tree->Key ) return Tree;
if ( what < Tree->Key )
return Search ( Tree->Left, what );
else return Search ( Tree->Right, what );
}

Чтобы написать программу на Си, надо определить функцию, возвращающую приоритет
операции, которая ей передана. Определим приоритет 1 для сложения и вычитания и приоритет
2 для умножения и деления.
int Priority ( char c )
{
switch ( c ) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
}
return 100;
}
Приведенная ниже программа строит требуемое дерево, используя эту функцию. Обратите
внимание, что при сравнении приоритета текущей операции с минимальным предыдущим
используется условие <=. За счет этого мы ищем именно последнюю операцию с минимальным
приоритетом, то есть, операцию, которая будет выполняться самой последней. Если бы мы
использовали знак <, то нашли бы первую операцию с наименьшим приоритетом и дерево
было бы построено неверно.
это не операция, пропускаем
Программирование на языке Си  К. Поляков, 1995-2002
23
PNode MakeTree (char Term[][10], int first, int last)
{
int MinPrt, i, k, prt;
PNode Tree = new Node;
if ( from == to ) {
strcpy (Tree->Data, Term[first]);
Tree->Left = NULL;
Tree->Right = NULL;
return Tree;
}
MinPrt = 100;
for ( i = first; i <= last; i ++ ) {
prt = Priority ( Term[i][0] );
if ( prt <= MinPrt ) {
MinPrt = prt;
k = i;
}
}
strcpy (Tree->Data, Term[k]);
Tree->Left = MakeTree(Term,first,k-1);
Tree->Right = MakeTree(Term,k+1,last);
return Tree;
}
Теперь обход этого дерева разными способами дает различные формы представления
соответствующего арифметического выражения.



Немного усложним задачу и разрешим использовать в выражении скобки одного вида
(допустим, круглые). Тогда при поиске в заданном диапазоне операции с минимальным
приоритетом не надо брать во внимание выражения в скобках (они выделены на рисунке).
a + ((b + c) * 5 + 3) * 7
Самый простой способ добиться этого эффекта – ввести счетчик открытых скобок nest. В
начале он равен нулю, с каждой найденной открывающей скобкой будем увеличивать его на 1, а
с каждой закрывающей - уменьшать на 1. Рассматриваются только те операции, которые
найдены при nest=0, то есть расположены вне скобок.
Если же ни одной такой операции не найдено, то мы имеем выражение, ограниченной
скобками, поэтому надо вызвать процедуру рекурсивно для диапазона from+1..last-1
(напомним, что мы предполагаем, что выражение корректно). Для сокращения записи показаны
только те части процедуры, которые изменяются:
создать конечную вершину- число
или переменную
искать ПОСЛЕДНЮЮ операцию с
наименьшим приоритетом (<=)
создать внутреннюю
вершину - знак операции
рекурсивно построить
поддеревья
выделить память под новую вершину
IV. Динамические структуры данных  К. Поляков, 1995-2002
24
PNode MakeTree (char Term[][10], int first, int last)
{
char c;
int MinPrt, i, k, prt;
int nest = 0;
PNode Tree = new Node;
...
MinPrt = 100;
for ( i = first; i <= last; i ++ ) {
c = Term[i][0];
if ( c == '(' ) { nest ++; continue; }
if ( c == ')' ) { nest --; continue; }
if ( nest > 0 ) continue;
prt = Priority ( c );
if ( prt <= MinPrt ) {
MinPrt = prt;
k = i;
}
}
if ( MinPrt == 100 &&
Term[first][0]== '(' && Term[last][0]==')' )
return MakeTree(Term, first+1, last-1);
...
return Tree;
}

Категория: Мои статьи | Добавил: Eskander (10.06.2010)
Просмотров: 479 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Copyright MyCorp © 2026
    Бесплатный конструктор сайтовuCoz