русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

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


Дата добавления: 2015-07-09; просмотров: 697; Нарушение авторских прав


Тема: “Классы динамических структур”

Пример 1: Класс, описывающий двунаправленный список

#include <iostream>

#include <conio.h>

#include <windows.h>

#include <stdlib.h>

using namespace std;

 

// структура, описывающая один узел:

struct Node

{

int data; // элемент данных

Node *next, *prev; // указатели на следующий и предыдущий узел

};

 

// класс для работы со списком:

class ListInt

{

/* указатели на начало, конец списка и на текущий узел (указатель на текущий узел используется многими функциями, поэтому объявим его как элемент данных класса): */

Node *front;

Node *back;

Node *token;

// функции ввода-вывода:

friend ostream& operator << (ostream&, ListInt&);

friend istream& operator >> (istream&, ListInt&);

public:

ListInt() {back = front = token = NULL;}

// конструктор по умолчанию

ListInt(int, int*); // основной конструктор

ListInt(const ListInt&); // конструктор копирования

~ListInt(); // деструктор

bool Empty() { return front == NULL ? true: false;}

// проверка, пустой ли список

void Add(int val); //добавляет элемент в конец списка

int Gettoken(); // текущий элемент данных

int GetSize(); // количество элементов списка

ListInt& operator () (int n, int v);

// операция, которая заменяет элемент с номером n на заданное значение v

// кроме того операция () является вспомогательной для операции +

ListInt& operator + ();

// операция, которая добавляет элемент в список в текущей позиции

};

// Определение функций:

// Основной конструктор

ListInt :: ListInt (int n, int* val)

// параметрами являются количество элементов массива и указатель на массив

{

back = front = token = NULL;

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



Add(val[i]); // добавляем элементы массива в список

}

// конструктор копирования:

ListInt :: ListInt(const ListInt& list)

{

back = front = token = NULL;

Node* ptr = list.front;

// указатель на текущий элемент копируемого объекта

while (ptr)

{

Add(ptr->data);

// добавляем в список элемент из копируемого списка

ptr = ptr->next;

// переходим к следующему элементу копируемого списка

}

}

 

// функция, которая добавляет элемент в конец списка:

void ListInt :: Add(int val)

{

Node *p = new Node; // создаем новый узел

p->data = val; // записываем элемент данных

if(Empty()) // если список еще пуст

{

front = back = p;

// добавляемый элемент становится первым и последним

p->next = p->prev = NULL;

// предыдущего и последующего элементов нет

}

else

{

back->next = p; // привязываем новый узел к последнему

p->prev=back; p->next = NULL; // определяем значения указателей

back=p; // новый узел становится последним

}

}

 

//функция ввода:

istream & operator >> (istream &is, ListInt& q)

{

q.~ListInt(); // Удаляем ранее существовавший список

int a; int k;

cout<<"Сколько элементов будете вводить? ";

is >> k;

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

{

cout << i+1 << ": "; is >> a;

q.Add(a);

}

return is;

}

 

//функция, которая определяет значение текущего элемента

int ListInt :: Gettoken()

{

if (token == NULL) token = front;

if (token)

{

int rv = token->data; //считываем значение из текущего узла

token = token->next; //текущим становится следующий узел

return rv;

}

else return 0;

}

 

// функция вывода:

ostream& operator << (ostream& os, ListInt& q)

{

Os << "< ";

q.token = q.front; // переходим в начало списка q

while(q.token) // пока список не закончен

{

if (q.token != q.front)

cout <<", ";

os << q.Gettoken(); // выводим очередной элемент списка

}

return os << ">" << endl;

}

 

//деструктор:

ListInt :: ~ListInt()

//Удаляет элементы cписка с конца:

{

while (back) // если список не пустой

{

token = back; // берем последний узел

back = back->prev; // предпоследний узел делаем последним

delete token; // удаляем узел

if (token==front) break;

// если удалили первый узел, то останавливаем цикл

}

}

 

// функция возвращает количество элементов списка

int ListInt::GetSize()

{

int count=0;

token = front;

while (token)

{

count++; // увеличиваем счетчик

token = token->next; // переходим к следующему узлу

}

return count;

}

 

// операция ():

ListInt& ListInt:: operator () (int n, int v)

// параметрами функции являются номер элемента и новое значение этого

// элемента

{

Node *ptr;

if (n <= GetSize())

{

// находим адрес элемента с заданным номером:

ptr = front;

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

ptr = ptr->next;

Node* tmp = new Node;

// создаем новый узел (он будет хранить копию заменяемого узла)

tmp->data = ptr->data; // копируем содержимое узла

tmp->prev = ptr->prev;

tmp->next = ptr->next;

front->prev = tmp; // временно подвязываем копию перед первым узлом списка

ptr->data = v; // заменяем значение текущего элемента на v

}

else // Если вставляем новый узел в конец списка

{

Node* tmp = new Node; // Создаем новый узел

tmp->data = v;

tmp->prev = back;

tmp->next = NULL;

front->prev = tmp;

// временно подвязываем его перед первым узлом списка

ptr = back;

back = tmp;

}

token = ptr;

return *this; // возвращаем текущий объект

}

 

// операция +

ListInt& ListInt:: operator + ()

{

token->next = front->prev;

/* за текущим узлом вставляем тот, который мы сохранили перед первым элементом */

front->prev = NULL; // теперь перед первым элементом ничего не стоит

return *this; // возвращаем указатель на текущий объект

}

//=========================================================

int main()

{

//Настройки шрифтов и региональных стандартов:

if(SetConsoleCP(1251)==0)

//проверка правильности установки кодировки символов для ввода

{

cerr<<"Fialed to set codepage!"<<endl;

/* если не удалось установить кодовую страницу, вывод сообщения об ошибке */

}

if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода

{

cerr<<"Failed to set OUTPUT page!"<<endl;

}

int a[]={1, -2, 3, -4, 5};

ListInt lista(5, a);

cout<<"Пример использования основного конструктора: \n";

cout << lista;

 

// пример использования операций () и + :

do

{

ListInt list;

cin >> list;

cout << list;

int data, n;

cout << "Задайте новый элемент списка ";

cin >> data;

cout << "Какой элемент заменить? ";

cin >> n;

if (n < 1 || n > list.GetSize())

cout << "Неверный номер\n";

else

{

list(n, data); // заменяем n-ый элемент на data

cout << list;

}

 

cout << "Задайте новый элемент списка ";

cin >> data;

cout << "Под каким номером вставить? ";

cin >> n;

if (n < 1 || n > list.GetSize()+1)

cout << "Неверный номер\n";

else

{

+list(n, data); // вставляем элемент data на n-ое место

// операция () выполняется перед операций +

cout << list;

}

} while (_getch() != 27);

return 0;

}

Пример 2: Класс, описывающий бинарное дерево

#include <iostream>

#include <conio.h>

#include <windows.h>

#include <fstream>

using namespace std;

 

// Вспомогательный класс, описывающий один узел:

class TreeNode

{

friend class Tree; /* Основной класс должен быть объявлен дружественным, чтобы он имел доступ к элементам узла */

// Элементы данных:

int data;

TreeNode* lPtr;

TreeNode* rPtr;

public:

// Конструктор:

TreeNode(int d)

{data = d; lPtr = NULL; rPtr = NULL;}

};

 

// Основной класс:

class Tree

{

TreeNode* rootPtr; // указатель на корневой узел (элемент данных)

// закрытые функции:

void Add(TreeNode*&,int); // добавляет новый элемент

void preOrder(TreeNode*); // Обход в ширину

void inOrder(TreeNode*); // Последовательный обход

void postOrder(TreeNode*); // Обратный обход

 

public:

// Конструктор:

Tree() {rootPtr = NULL;}

// открытые функции, которые будет использовать главная программа:

void Add( int);

void preOrder();

void inOrder();

void postOrder();

};

 

// Определение функций:

//Функция, которая добавляет узел к дереву:

void Tree :: Add(int m)

{

Add(rootPtr, m);

/* Здесь и далее перегрузка функций требуется, поскольку главная программа не имеет доступа к корневому узлу дерева, поэтому единственное назначение этого вызова функции Add() – передать адрес корневого узла. */

}

/* Основная функция, которая обходит дерево и привязывает новый узел к дереву: */

void Tree :: Add(TreeNode*& ptr, int m)

{

if (!ptr)

/* Если текущий указатель равен 0, к нему подвязываем новый узел

или создаем корневой */

ptr = new TreeNode(m);

/* благодаря тому, что параметр ptr объявлен как ссылка на указатель, уста­навливается значение указателя на корневой узел или изменяется значение указателя в том узле, к которому привязывается новый */

else

{

if (m < ptr->data) Add(ptr->lPtr, m);

// если новый элемент меньше значения в текущем узле, идем налево

else if (m > ptr->data) Add(ptr->rPtr, m);

// в противном случае - направо

// если встречается повторяющееся значение, то оно игнорируется, благодаря этому все элементы дерева будут различны

}

}

/* три нижеследующие функции отличаются только последовательностью выполнения операторов и благодаря этому позволяют выводить элементы дерева на экран в различном порядке */

void Tree :: preOrder()

{

preOrder(rootPtr);

}

 

// обход дерева “по ширине”:

void Tree :: preOrder(TreeNode* ptr)

{

if (ptr)

{

cout << ptr->data << " "; // выводим элемент

preOrder(ptr->lPtr); // спускаемся влево

preOrder(ptr->rPtr); // спускаемся вправо

}

}

 

// Последовательный обход

void Tree :: inOrder()

{

inOrder(rootPtr);

}

 

// обход в порядке возрастания:

void Tree :: inOrder(TreeNode* ptr)

{

if (ptr)

{

inOrder(ptr->lPtr);

cout << ptr->data << " ";

inOrder(ptr->rPtr);

}

}

 

// Обход в обратном направлении:

void Tree :: postOrder()

{

postOrder(rootPtr);

}

 

void Tree :: postOrder(TreeNode* ptr)

{

if (ptr)

{

postOrder(ptr->lPtr);

postOrder(ptr->rPtr);

cout << ptr->data << " ";

}

}

 

// Пример использования класса:

int main()

{

//Настройки шрифтов и региональных стандартов:

if(SetConsoleCP(1251)==0)

//проверка правильности установки кодировки символов для ввода

{

cerr<<"Fialed to set codepage!"<<endl;

}

if(SetConsoleOutputCP(1251)==0)//тоже самое для вывода

{

cerr<<"Failed to set OUTPUT page!"<<endl;

}

Tree tree; // Объявляем объект

double x;

// Открываем файл с данными:

ifstream file("numbers.txt");

if (file)

{

cout << "Прочитана последовательность: \n";

do

{

file>>x;

if (!file.eof())

{

cout << x << " ";

tree.Add(x); // добавляем элемент к дереву

}

} while (!file.eof());

cout<<endl;

 

cout <<"Обход в ширину: \n";

tree.preOrder();

cout<<endl;

 

cout <<"Отсортированная последовательность: \n";

tree.inOrder();

cout<<endl;

 

cout <<"Обратная последовательность: \n";

tree.postOrder();

cout<<endl;

 

}

else cout << "Файл не найден\n";

_getch();

return 0;

}

Пример набора данных:

65 34 77 25 38 70 83 21 33 38 88 15 11 14 90 83 99


Схема дерева для этого набора данных:

 
 


Результат работы программы:

Прочитана последовательность:

65 34 77 25 38 70 83 21 33 38 88 15 11 14 90 83 99

Обход в ширину:

65 34 25 21 15 11 14 33 38 77 70 83 88 90 99

Отсортированная последовательность:

11 14 15 21 25 33 34 38 65 70 77 83 88 90 99

Обратная последовательность:

14 11 15 21 33 25 38 34 70 99 90 88 83 77 65

 




<== предыдущая лекция | следующая лекция ==>
Задания для самостоятельного выполнения | Задания для самостоятельного выполнения


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 1.381 сек.