(1)АСД курс / 2_semestr_lab / Лабораторные работы
.docxЛабораторная работа № 6
Тема: Знакомство с деревьями. Реализация простого дерева. Прямой обход дерева.
Цель: Закрепить теоретический материал по организации деревьев.
Ход работы
1) Запустите Microsoft Visual Studio и создайте консольное приложение C#.
2) Проанализируйте представленный ниже код класса, реализующего узел дерева, добавьте его в свой проект. После чего добавьте комментарии объясняющие работу кода внутри его методов:
class Node
{
static int cnt;
public String Data; // данные которые хранит узел
public Node Parent; // ссылка на родительский узел
public List<Node> Childs; // список дочерних узлов
// конструктор узла
public Node(Node parent, String data)
{
Data = data;
Parent = parent;
Childs = new List<Node>();
if (parent != null)
{
parent.Childs.Add(this);
}
}
// функция печати, которая проходит дерево в прямом порядке
public void PrintForward(Node node)
{
cnt++;
Console.WriteLine(node.Data + " " + cnt.ToString());
for (int i = 0; i < node.Childs.Count; i++)
{
PrintForward(node.Childs[i]);
}
}
}
3) Проанализируйте представленный ниже код метода Main, добавьте его к себе в проект. После чего добавьте комментарии, объясняющие его работу:
static void Main(string[] args)
{
Node N = new Node(null, "root");
Random R = new Random();
for (int i = 0; i < R.Next(2, 5); i++)
{
Node T = new Node(N, "|-- Node " + i.ToString());
for (int j = 0; j < R.Next(2, 5); j++)
{
new Node(T, " |-- Node " + j.ToString());
}
}
Console.WriteLine("Прямой обход дерева на основе связных списков");
N.PrintForward(N);
Console.WriteLine("");
Console.ReadKey();
}
4) Самостоятельно, добавьте в метод Main команду, вызова метода PrintForward так что бы вывод дерева начинался с какого либо дочернего узла.
Лабораторная работа № 7
Тема: Работа с двоичными деревьями. Обход деревьев в прямом, поперечном и обратном порядке
Цель: Закрепить теоретический материал по организации двоичных деревьев и способам их обхода.
Ход работы
1) Запустите Microsoft Visual Studio и создайте консольное приложение C#.
2) Проанализируйте представленный ниже код класса, реализующего узел двоичного дерева, добавьте его в свой проект. После чего добавьте комментарии объясняющие работу кода внутри его методов:
class TreeNode {
public TreeNode Left; // ссылка на левый дочерний узел
public TreeNode Right; // ссылка на правый дочерний узел
public TreeNode Parent; // ссылка на родителя
public int Key; // ключь узла в дереве
// конструктор узла
public TreeNode(TreeNode parent, int key)
{
this.Parent = parent;
this.Key = key;
}
// функция добавления узла в дерево
public bool AddNode(int key)
{
if (key < this.Key)
{
if (this.Left != null)
return this.Left.AddNode(key);
else
{
this.Left = new TreeNode(this, key);
return true;
}
}
else if (key > this.Key)
{
if (this.Right != null)
return this.Right.AddNode(key);
else
{
this.Right = new TreeNode(this, key);
return true;
}
}
else
{
return false;
}
}
// процедура вывода дерева
public void print(TreeNode node, int level)
{
if(node.Parent != null)
Console.WriteLine(new String(' ', level) + "|--" + node.Key.ToString());
else
Console.WriteLine(node.Key.ToString());
if (node.Left != null)
print(node.Left, level + 1);
if (node.Right != null)
print(node.Right, level + 1);
level++;
}
// прямой порядок обхода
public void preOrderTravers(TreeNode node)
{
Console.Write(node.Key.ToString() + ", ");
if (node.Left != null)
preOrderTravers(node.Left);
if (node.Right != null)
preOrderTravers(node.Right);
}
}
3) Проанализируйте представленный ниже код метода Main, добавьте его к себе в проект. После чего добавьте комментарии, объясняющие его работу:
static void Main(string[] args)
{
TreeNode tree = null;
Console.Write("Введите число узлов: ");
int cnt = Convert.ToInt32(Console.ReadLine());
int i = 0;
int key = 0;
while(i < cnt) {
Console.Write("Введите ключ добавляемого узла: ");
key = Convert.ToInt32(Console.ReadLine());
if (tree == null)
tree = new TreeNode(null, key);
else
if (!tree.AddNode(key))
{
Console.WriteLine("Ключ " + key.ToString() + " уже есть в дереве.");
i--;
}
i++;
}
tree.print(tree, 0);
Console.WriteLine("Порядок обхода узлов при прямом обходе");
tree.preOrderTravers(tree);
Console.WriteLine("");
Console.WriteLine("Для завершения нажмите Enter");
Console.ReadKey(true);
}
4) Самостоятельно, ориентируясь на код метода preOrderTravers, составьте методы, реализующие обход дерева в поперечном и обратном порядке.
Лабораторная работа № 8
Тема: Поиск данных в массивах.
Цель: Закрепить теоретический материал по организации поиска в массивах.
Ход работы
1) Разработайте консольную программу, которая запрашивает у пользователя размер массива, выделяет под него память, заполняет его автоматически упорядоченными данными, выводит массив на экран.
2) Напишите функцию, которая будет выполнять последовательный поиск элемента в массиве по заданному ключу (ключ поиска вводится пользователем). В качестве параметров функция должна принимать массив и ключ для поиска. Возвращаемое значение – индекс элемента, удовлетворяющий ключу поиска, если такого элемента в массиве нет, функция возвращает -1. В функции предусмотрите подсчет количества итераций, которые потребуются для поиска элемента в массиве. Выведите кол-во итераций потребовавшихся для поиска элемента на экран.
3) Используя приведенную ниже функцию двоичного поиска элемента в массиве, организуйте поиск элемента в массиве, по ключу который задает пользователь. Добавьте поясняющие комментарии к программному коду этой функции. Организуйте подсчет количества итераций, которые потребуются для поиска элемента в массиве. Выведите кол-во итераций потребовавшихся для поиска элемента на экран.
static int BinarySearch(int[] array, int key)
{
int left = 0;
int right = array.Length;
int mid = 0;
while (!(left >= right))
{
mid = left + (right - left) / 2;
if (array[mid] == key)
return mid;
if (array[mid] > key)
right = mid;
else
left = mid + 1;
}
return -1;
}
Лабораторная работа № 9
Тема: Поиск данных в массивах.
Цель: Закрепить теоретический материал по организации поиска в массивах.
Ход работы
1) Разработайте консольную программу, которая запрашивает у пользователя размер матрицы, выделяет под неё память, заполняет её автоматически упорядоченными данными, выводит матрицу на экран.
2) Напишите функцию, которая будет выполнять последовательный поиск элемента в матрице по заданному ключу (ключ поиска вводится пользователем). В качестве параметров функция должна принимать ссылку на матрицу, ключ для поиска, и ссылки на переменные для записи индексов найденного элемента. Возвращаемое значение – true если элемент найден, иначе false. В функции предусмотрите подсчет количества итераций, которые потребуются для поиска элемента в матрице. Выведите кол-во итераций потребовавшихся для поиска элемента на экран.
3) Используя приведенную ниже функцию блочного поиска элемента в матрице, организуйте поиск элемента в матрице, по ключу который задает пользователь. Добавьте поясняющие комментарии к программному коду этой функции. Организуйте подсчет количества итераций, которые потребуются для поиска элемента в матрице. Выведите кол-во итераций потребовавшихся для поиска элемента на экран.
static bool BlockSearch(int[,] array, int key, ref int r, ref int c)
{
bool result = false;
r = -1;
c = -1;
for (int i = 0; i < array.GetLength(0); i++)
{
if (key <= array[i, array.GetLength(1) - 1])
{
if (key == array[i, array.GetLength(1) - 1])
{
r = i;
c = array.GetLength(1) - 1;
result = true;
return result;
}
for (int j = 0; j < array.GetLength(1) - 1; j++)
{
if (key == array[i, j])
{
r = i;
c = j;
result = true;
return result;
}
}
}
}
return result;
}
Лабораторная работа № 10
Тема: Поиск данных в строках.
Цель: Закрепить теоретический материал по организации поиска в строках.
Ход работы
1) Разработайте консольную программу, которая запрашивает у пользователя исходную строку, затем запрашивает у пользователя подстроку для поиска.
2) Напишите функцию, которая будет выполнять простой последовательный поиск подстроки в исходной строке. Функция должна принимать два параметра исходную строку, подстроку для поиска. Результат, возвращаемый функцией это позиция начала вхождения подстроки в строку, если подстроки в строке нет функция возвращает -1.
3) Используя нижеприведенные фрагменты кода алгоритма поиска Бойера-Мура, организуйте поиск подстроки в строке в вашей программе.
static Dictionary<char, int> ShiftTable;
static int TamplateLength;
public static void ShiftBM(string s)
{
ShiftTable = null;
ShiftTable = new Dictionary<char, int>();
TamplateLength = s.Length;
for (int i = 0; i < s.Length - 1; i++)
{
if (ShiftTable.ContainsKey(s[i]))
ShiftTable[s[i]] = s.Length - i - 1;
else
ShiftTable.Add(s[i], s.Length - i - 1);
}
}
public static int GetShift(char key)
{
if (ShiftTable.ContainsKey(key))
return ShiftTable[key];
else
return TamplateLength;
}
public static int BM(string substr, string s)
{
if (TamplateLength > s.Length)
return -1;
ShiftBM(substr);
int i = TamplateLength - 1;
int j = i;
int k = i;
int c = 0;
while (j >= 0 && i <= s.Length - 1)
{
j = TamplateLength - 1;
k = i;
c = 0;
while (j >= 0 && s[k] == substr[j])
{
k--;
j--;
c++;
}
if (c == 0)
i = i + GetShift(s[i]);
else
i++;
}
if (k >= s.Length - TamplateLength)
{
return -1;
}
else
{
return k + 1;
}
}