Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лабораторная работа №2 Вариант №21

.doc
Скачиваний:
21
Добавлен:
20.06.2014
Размер:
337.92 Кб
Скачать

2

ФЕДЕРАЛЬНОЕ АГЕНТСТВО ПО ОБРАЗОВАНИЮ

ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ

ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ

ЛИПЕЦКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

КАФЕДРА АВТОМАТИЗИРОВАННЫХ СИСТЕМ УПРАВЛЕНИЯ

Лабораторная работа №2

по дисциплине

«Структуры и алгоритмы»

на тему:

«АВЛ и В-Деревья»

Студент

подпись, дата

фамилия, инициалы

Группа

Принял

Журавлева М.Г.

ученая степень, звание

подпись, дата

фамилия, инициалы

Липецк 2010

  1. Задание

Осуществить программную реализацию АВЛ- или B-дерева заданного порядка, с указанным типом ключа, выбрав из табл. 2 приложения соответствующие номеру варианта исходные параметры.

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

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

  1. Листинг программы

#include <conio.h>

#include <stdio.h>

#include <locale.h>

#include <stdlib.h>

#include <locale.h>

#include <windows.h>

struct tree

{

int key;

int h;

tree *left;

tree *right;

};

tree* add(tree *root, int x)

{

if(!root)

{

root=(tree *)malloc(sizeof(tree));

root->key=x;

root->left=0;

root->right=0;

root->h=1;

}

else if(x < root->key)

{

root->left=add(root->left, x);

if(root->h<=root->left->h)

root->h=root->left->h+1;

}

else if(x > root->key)

{

root->right=add(root->right, x);

if(root->h<=root->right->h)

root->h=root->right->h+1;

}

return root;

}

void obhod(tree *root)

{

printf("%d[%d]",root->key,root->h);

printf("(");

if(root->left)

obhod(root->left);

printf(",");

if(root->right)

obhod(root->right);

printf(")");

}

tree *hight(tree *root)

{

if(!root->left && !root->right)

{

root->h=1;

return root;

}

if(root->left)

{

root->left=hight(root->left);

root->h=root->left->h+1;

}

if(root->right)

{

root->right=hight(root->right);

if(root->h <=root->right->h)

root->h=root->right->h+1;

}

return root;

}

tree *small_right_rotate(tree *root)

{

tree *a=root;

tree *b=root->right;

a->right=b->left;

b->left=a;

a->h=1;

b->h=1;

if(a->left)

a->h=a->left->h+1;

if(a->right)

a->h=a->right->h+1;

if(a->right && a->left)

if(a->right->h > a->left->h)

a->h=a->right->h+1;

else

a->h=a->left->h+1;

if(b->left)

b->h=b->left->h+1;

if(b->right)

b->h=b->left->h+1;

if(b->right && b->left)

if(b->right->h > b->left->h)

b->h=b->right->h+1;

else

b->h=b->left->h+1;

return b;

}

tree *small_left_rotate(tree *root)

{

tree *b=root->left;

tree *a=root;

a->left=b->right;

b->right=a;

a->h=1;

b->h=1;

if(a->left)

a->h=a->left->h+1;

if(a->right)

a->h=a->right->h+1;

if(a->right && a->left)

if(a->right->h > a->left->h)

a->h=a->right->h+1;

else

a->h=a->left->h+1;

if(b->left)

b->h=b->left->h+1;

if(b->right)

b->h=b->left->h+1;

if(b->right && b->left)

if(b->right->h > b->left->h)

b->h=b->right->h+1;

else

b->h=b->left->h+1;

return b;

}

tree *big_right_rotate(tree *root)

{

tree *a=root;

tree *b=root->right;

tree *c=b->left;

a->right=c->left;

b->left=c->right;

c->left=a;

c->right=b;

a->h=1;

b->h=1;

if(a->left)

a->h=a->left->h+1;

if(a->right)

a->h=a->right->h+1;

if(a->right && a->left)

if(a->right->h > a->left->h)

a->h=a->right->h+1;

else

a->h=a->left->h+1;

if(b->left)

b->h=b->left->h+1;

if(b->right)

b->h=b->right->h+1;

if(b->right && b->left)

if(b->right->h > b->left->h)

b->h=b->right->h+1;

else

b->h=b->left->h+1;

if(a->h > b->h)

c->h=a->h+1;

else

c->h=b->h+1;

return c;

}

tree *big_left_rotate(tree *root)

{

tree *a=root;

tree *b=root->left;

tree *c=b->right;

a->left=c->right;

b->right=c->left;

c->left=b;

c->right=a;

a->h=1;

b->h=1;

if(a->left)

a->h=a->left->h+1;

if(a->right)

a->h=a->right->h+1;

if(a->right && a->left)

if(a->right->h > a->left->h)

a->h=a->right->h+1;

else

a->h=a->left->h+1;

if(b->left)

b->h=b->left->h+1;

if(b->right)

b->h=b->right->h+1;

if(b->right && b->left)

if(b->right->h > b->left->h)

b->h=b->right->h+1;

else

b->h=b->left->h+1;

if(a->h > b->h)

c->h=a->h+1;

else

c->h=b->h+1;

return c;

}

tree *balance(tree *root)

{

if(root->left && root->left->h>2)

root->left=balance(root->left);

if(root->right && root->right->h>2)

root->right=balance(root->right);

int r=0,rr=0,rl=0,rll=0,rlr=0,rrl=0,rrr=0;

r=root->h;

if(root->right)

{

rr=root->right->h;

if(root->right->left)

rrl=root->right->left->h;

if(root->right->right)

rrr=root->right->right->h;

}

if(root->left)

{

rl=root->left->h;

if(root->left->left)

rll=root->left->left->h;

if(root->left->right)

rlr=root->left->right->h;

}

if((root->right && (rr-rl)==2 && (rrl <= rrr)))

root=small_right_rotate(root);

else

if((root->left && (rl-rr)==2 && (rlr <= rll)))

root=small_left_rotate(root);

else

if(root->right && root->right->left && (rr-rl)==2 && (rrl > rrr))

root=big_right_rotate(root);

else

if(root->left && root->left->right &&(rl-rr)==2 && (rlr > rll))

root=big_left_rotate(root);

return root;

}

tree *right_most_child(tree *root)

{

if(!root->right)

return root;

else

return right_most_child(root->right);

}

tree *parent(tree *root,int key)

{

if(root->left)

{

if(key==root->left->key)

return root;

if(key<root->key)

return parent(root->left, key);

}

if(root->right)

{

if(key==root->right->key)

return root;

if(key>root->key)

return parent(root->right, key);

}

return root;

}

tree *return_key(tree *root, int key)

{

if(root)

{

if(root->key==key)

return root;

if(key<root->key)

return return_key(root->left,key);

if(key>root->key)

return return_key(root->right,key);

}

else return NULL;

}

tree *udal(tree *root,int key)

{

tree *p,*k,*r;

k=return_key(root,key);

if(k)

{

if(k->left)

r=right_most_child(k->left);

else r=NULL;

p=parent(root,key);

if(root->key==key)

if(root->left)

{

tree *n;

n=right_most_child(root->left);

n->right=root->right;

root=root->left;

return root;

}

else

{

root=root->right;

return root;

}

if(p->right==k)

if(!k->left)

p->right=k->right;

else if(!k->right)

p->right=k->left;

else

{

r->right=k->right;

p->right=k->left;

return root;

}

if(p->left==k)

if(!k->right)

p->left=k->left;

else if(!k->left)

p->left=k->right;

else

{

r->right=k->right;

p->left=k->left;

return root;

}

return root;

}

else return NULL;

}

tree *del(tree *root)

{

tree *k;

int elem;

printf("\nКакой узел вы хотите удалить?");

scanf("%d",&elem);

root=udal(root,elem);

root=hight(root);

if(root->h>2)

root=balance(root);

return root;

}

tree *generation(tree *root)

{

int n;

printf("\nВведите количество элементов: ");

scanf("%d", &n);

srand(2);

for(int i=0;i<n;i++)

root=add(root,rand()%100);

return root;

}

void main()

{

setlocale(LC_ALL,"Rus");

tree *root=NULL, *dop;

int key;

char c='1';

while(c!='0')

{

system("cls");

printf("\n1.Добавить\n2.Удалить\n3.Вывести\n4.Генерация\n5.Удалить дерево\n0.Выход\n");

c=getch();

switch(c)

{

case '1':

printf("\nВведите ключ: ");

scanf("%d",&key);

root=add(root,key);

if(root && root->h>2)

root=balance(root);

break;

case '2':

root=del(root);

break;

case '3':

if(root)

obhod(root);

getch();

break;

case '4':

root=generation(root);

if(root && root->h>2)

root=balance(root);

break;

case '5':

free(root);

root=NULL;

break;

}

}}

  1. Контрольный пример

  1. Блок-схема

5. Вывод

При выполнении данной лабораторной работы я получил навыки программирования сильноветвящихся деревьев.

  1. Список использованной литературы

  1. Шилдт Г. Искусство программирования на C++. БХВ.2005

  2. Шилдт Г. C++ Руководство для начинающих. Вильямс.2005

  3. Страуструп Б. Язык программирования С++. Специальное издание, 3-изд. Бином.2004