Федеральное государственное бюджетное образовательное учреждение высшего образования «РОССИЙСКАЯ АКАДЕМИЯ НАРОДНОГО ХОЗЯЙСТВА И ГОСУДАРСТВЕННОЙ СЛУЖБЫ ПРИ ПРЕЗИДЕНТЕ РОССИЙСКОЙ ФЕДЕРАЦИИ» НИЖЕГОРОДСКИЙ ИНСТИТУТ УПРАВЛЕНИЯ – филиал РАНХиГС Факультет управления Кафедра Информатики и информационных технологий Направление подготовки / специальность: 09.04.03 Прикладная информатика Направленность (профиль) / специализация: Корпоративные информационные системы управления Отчет по лабораторным работам по дисциплине: Структуры данных и их использование в программировании АВТОР Обучающийся(иеся) 2 курса группы Ик-721 заочной формы обучения _____________ Калашников Савелий Сергеевич (подпись) (фамилия, инициалы) РУКОВОДИТЕЛЬ Старший преподаватель (ученая степень, ученое звание) оценка ____________________________________ «_____» __________________ 20____ г. (дата защиты) _____________ (подпись) Нижний Новгород, 2023г. Чистов В.С. (фамилия, инициалы) Практическое задание 1 ___________________________________________________ 3 Задание 1 _____________________________________________________________________ 3 Задание 2 _____________________________________________________________________ 6 Задание 3 _____________________________________________________________________ 8 Практическое задание 2 __________________________________________________ 11 Задание 1 ____________________________________________________________________ 11 Задание 2 ____________________________________________________________________ 13 Задание 3 ____________________________________________________________________ 15 Задание 4 ____________________________________________________________________ 17 Задание 5 ____________________________________________________________________ 19 Задание 6 ____________________________________________________________________ 21 Задание 7 ____________________________________________________________________ 25 Практическое задание 3 __________________________________________________ 27 Задание 1 ____________________________________________________________________ 27 Задание 2 ____________________________________________________________________ 27 Практическое задание 4 __________________________________________________ 36 Задание 1 ____________________________________________________________________ 36 Задание 2 ____________________________________________________________________ 38 Практическое задание 5 __________________________________________________ 39 Задание 1 ____________________________________________________________________ 39 Практическое задание 1 Задание 1 Разработайте алгоритм, который запрашивает у пользователя четыре целых числа и затем определяет, есть ли среди введенных чисел одинаковые или нет. Нарисуйте блок-схему алгоритма. Программный код может быть реализован на одном из следующих языков программирования: С, С++, С#, Java. Блок-схема Начало Ввод array equal = false i=0; i<N-1; i++ j = i + 1; j < N; j++ equal |= array[i] == array[j] Нет equal Вывод "Нет одинаковых" Да Вывод "Есть одинаковые" Конец 3 Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr1_1 { class Program { static void Main(string[] args) { //Ввод const int N = 4; int[] array = new int[N]; for (int i=0; i<array.Length; i++) { Console.Write("a[{0}]=", i); array[i] = Convert.ToInt32(Console.ReadLine()); } //Проверка bool equal = false; for (int i=0; i<N-1; i++) { for (int j = i + 1; j < N; j++) equal |= array[i] == array[j]; } if (equal) Console.WriteLine("Есть одинаковые"); else Console.WriteLine("Нет одинаковых"); Console.ReadKey(); } } } 4 Вывод результатов на экран 5 Задание 2 Разработайте алгоритм, который запрашивает у пользователя четыре целых числа и затем находит третье по величине число, если оно существует. Нарисуйте блок-схему алгоритма. Программный код может быть реализован на одном из следующих языков программирования: С, С++, С#, Java. Блок-схема Начало Ввод array Array.Sort(array) Вывод array[N-3] Конец 6 Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr1_2 { class Program { static void Main(string[] args) { //Ввод const int N = 4; int[] array = new int[N]; for (int i = 0; i < array.Length; i++) { Console.Write("a[{0}]=", i); array[i] = Convert.ToInt32(Console.ReadLine()); } //Сортировка Array.Sort(array); //Вывод Console.WriteLine(array[N-3]); Console.ReadKey(); } } } Вывод результатов на экран 7 Задание 3 Разработайте алгоритм, который случайным образом задает четыре целых числа и затем определяет максимальное и минимальное число, а также находит количество максимальных и минимальных чисел среди введенных. Нарисуйте блок-схему алгоритма. Программный код может быть реализован на одном из следующих языков программирования: С, С++, С#, Java. Блок-схема Начало Ввод array Min = array[0] Max = Min i = 1; i < array.Length; i++ Min = Math.Min(Min, array[i]) MinCount = 0 Max = Math.Max(Max, array[i]) MaxCount = 0 i = 0; i < array.Length; i++ Min == array[i] MinCount++ Max == array[i] Вывод Min, MinCount, Max, MaxCount MaxCount++ Конец 8 Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr1_3 { class Program { static void Main(string[] args) { const int N = 4; Random random = new Random(); int[] array = new int[N]; for (int i = 0; i < array.Length; i++) array[i] = random.Next(0, 10); //Вывод массива для контроля for (int i = 0; i < array.Length; i++) Console.Write("{0} ",array[i]); Console.WriteLine(); int Min = array[0], Max = Min; for (int i = 1; i < array.Length; i++) { Min = Math.Min(Min, array[i]); Max = Math.Max(Max, array[i]); } int MinCount = 0, MaxCount = 0; for (int i = 0; i < array.Length; i++) { if (Min == array[i]) MinCount++; if (Max == array[i]) MaxCount++; } Console.WriteLine("Min = {0}, count = {1}", Min, MinCount); Console.WriteLine("Max = {0}, count = {1}", Max, MaxCount); Console.ReadKey(); } } } 9 Вывод результатов на экран 10 Практическое задание 2 Задание 1 Создайте одномерный массив. Выведите его содержимое на экран. Выполните реверс содержимого массива (переверните наоборот: первый элемент меняется местами с последним, второй с предпоследним и т.д.). Выведите содержимое на экран. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_1 { class Program { static void Print(int[] array) { for (int i = 0; i < array.Length; i++) Console.Write("{0} ", array[i]); Console.WriteLine(); } static void Main(string[] args) { const int N = 10; Random random = new Random(); int[] array = new int[N]; for (int i = 0; i < array.Length; i++) array[i] = random.Next(0, 10); //Вывод массива для контроля Print(array); for (int i = 0; i < array.Length/2; i++) { int temp = array[i]; array[i] = array[N - i - 1]; array[N - i - 1] = temp; } Print(array); Console.ReadKey(); } } } 11 Вывод результатов на экран 12 Задание 2 Решить уравнение a*х=b для пяти пар значений a и b, заданных в виде двух массивов. Результат поместить в массив X. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_2 { class Program { static void Print(double[] array, string Header) { Console.Write(Header); for (int i = 0; i < array.Length; i++) Console.Write("{0} ", array[i].ToString("0.000")); Console.WriteLine(); } static Random random = new Random(); static double[] Create(int size, double min, double max) { double[] result = new double[size]; for (int i = 0; i < size; i++) result[i] = random.NextDouble() * (max - min) + min; return result; } static void Main(string[] args) { int N = 5; double[] a = Create(N, 1, 2); Print(a, "a:"); double[] b = Create(N, -2, 2); Print(b, "b:"); double[] X = new double[N]; for (int k=0; k< N; k++) { //a*x=b --> x = b/a if (a[k] == 0) X[k] = 0; else X[k] = b[k] / a[k]; } Print(X, "X:"); Console.ReadKey(); } 13 } } Вывод результатов на экран 14 Задание 3 Дан массив A(20). Определить, сколько его элементов с номерами 1, 2, 4, 8, 16 имеют значение меньше, чем 0.25. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_3 { class Program { static void Print(double[] array, string Header) { Console.Write(Header); for (int i = 0; i < array.Length; i++) Console.Write("{0} ", array[i].ToString("0.000")); Console.WriteLine(); } static Random random = new Random(); static double[] Create(int size, double min, double max) { double[] result = new double[size]; for (int i = 0; i < size; i++) result[i] = random.NextDouble() * (max - min) + min; return result; } static void Main(string[] args) { const int N = 20; double[] A = Create(N, 0, 1); Print(A, "A = "); //1, 2, 4, 8, 16 - степени двойки int count = 0; for (int index = 1; index <= 16; index <<= 1) if (A[index] < 0.25) { count++; Console.WriteLine("index = {0}, value = {1}", index, A[index].ToString("0.000")); } Console.WriteLine("Count= {0}", count); Console.ReadKey(); } 15 } } Вывод результатов на экран 16 Задание 4 Дана матрица B(4,4). Среди элементов главной диагонали найти наименьший, вывести его, и, если он меньше некоторого числа K, то ко всем элементам строки, в которой расположен наименьший элемент, прибавить 1. Программа using System.Text; using System.Threading.Tasks; namespace Pr2_4 { class Program { static void Print(double[,] array, string Header) { Console.WriteLine(Header); for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) Console.Write("{0} ", array[i,j].ToString("0.000")); Console.WriteLine(); } } static Random random = new Random(); static double[,] Create(int rows,int columns, double min, double max) { double[,] result = new double[rows,columns]; for (int i = 0; i < result.GetLength(0); i++) for (int j = 0; j < result.GetLength(1); j++) result[i,j] = random.NextDouble() * (max - min) + min; return result; } static void Main(string[] args) { int Rows = 4, Columns = Rows; double[,] B = Create(Rows, Columns, 0, 8); double K = 5; Print(B, "B"); Console.WriteLine("K = {0}", K); //Найти минимум главной диагонали int row = 0; for (int r = 0; r < Rows; r++) if (B[r, r] < B[row, row]) 17 row = r; Console.WriteLine("B[{0},{0}]={1}", row, B[row, row].ToString("0.000")); if (B[row, row] < K) { for (int col = 0; col < Columns; col++) B[row, col]++; Print(B, "B'"); } else Console.WriteLine("Не модифицирован"); Console.ReadKey(); } } } Вывод результатов на экран 18 Задание 5 Из массивов X(15) и Y(10) построить матрицу A(5,5) таким образом, чтобы элементы массива X были расположены на главной ди¬агонали и выше ее. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_5 { class Program { //Вывод одномерного массива static void Print(double[] array, string Header) { Console.Write(Header); for (int i = 0; i < array.Length; i++) Console.Write("{0} ", array[i].ToString("0.0")); Console.WriteLine(); } //Вывод двумерного массива static void Print(double[,] array, string Header) { Console.WriteLine(Header); for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) Console.Write("{0} ", array[i, j].ToString("0.0")); Console.WriteLine(); } } static Random random = new Random(); static double[] Create(int size, double min, double max) { double[] result = new double[size]; for (int i = 0; i < size; i++) result[i] = random.NextDouble() * (max - min) + min; return result; } static void Main(string[] args) { 19 double[] X = Create(15, 0, 9); Print(X, "X="); double[] Y = Create(10, 0, 9); Print(Y, "Y="); double[,] A = new double[5, 5]; int y = 0, x = 0; for (int r = 0; r < 5; r++) for (int c = 0; c < 5; c++) if (r <= c) A[r, c] = X[x++]; else A[r, c] = Y[y++]; Print(A, "A"); Console.ReadKey(); } } } Вывод результатов на экран 20 Задание 6 Создайте двумерный массив А(N,M). Значения N и M вводит пользователь с клавиатуры. Элементы массива могут принимать 2 значения – 0 и 1. Количество 1 (K) определяет пользователь. Эти 1 распределяются по массиву случайным образом. Должно получиться на подобие следующего: N=3, M=5, K=4 00100 10010 00100 На экране вывести картинку массива и его зеркальное отображение по всем направлениям: 00100 | 00100 10010 | 01001 00100 | 00100 ---------------- - это в представлении массива 00100 | 00100 10010 | 01001 00100 | 00100 * * * * * * * * - это должно быть на экране * * * * * * * * Массив будет только один исходный. Для вывода на экран 21 используйте вложенный цикл. За счет правильного выбора индексов (счетчиков массива) выводятся зеркальные копии исходного массива. При выводе на экран используйте пробел, если значение массива равно 0, и *, если значение – 1. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_6 { class Program { static void Print(int[,] array) { for (int i = 0; i < array.GetLength(0); i++) { for (int j = 0; j < array.GetLength(1); j++) Console.Write(array[i, j]); Console.WriteLine(); } } static Random random = new Random(); static int[,] Create(int rows, int columns, int K) { int[,] result = new int[rows, columns]; if (K > rows * columns) K = rows * columns; //Ограничение while (K>0) { int row = random.Next(rows); int col = random.Next(columns); if (result[row,col]==0) { result[row, col] = 1; K--; } } return result; } static void SpecialPrint(int[,] A) { int Rows = A.GetLength(0); 22 int Cols = A.GetLength(1); string S = " *"; for (int row=0; row< Rows; row++) { for (int col = 0; col < Cols; col++) Console.Write(S[A[row, col]]); Console.Write("|"); for (int col = Cols-1; col >=0 ; col--) Console.Write(S[A[row, col]]); Console.WriteLine(); } for (int col = 0; col < 2 * Cols + 1; col++) Console.Write("-"); Console.WriteLine(); for (int row = Rows-1; row >= 0; row--) { for (int col = 0; col < Cols; col++) Console.Write(S[A[row, col]]); Console.Write("|"); for (int col = Cols - 1; col >= 0; col--) Console.Write(S[A[row, col]]); Console.WriteLine(); } } static void Main(string[] args) { Console.Write("N = "); int N = Convert.ToInt32(Console.ReadLine()); Console.Write("M = "); int M = Convert.ToInt32(Console.ReadLine()); Console.Write("K = "); int K = Convert.ToInt32(Console.ReadLine()); int[,] A = Create(N, M, K); Print(A); SpecialPrint(A); Console.ReadKey(); } } } 23 Вывод результатов на экран 24 Задание 7 Создайте одномерный массив, который содержит полный набор возможных значений типа UInt16, кроме одного. Определите, какого числа не хватает. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr2_7 { class Program { static Random random = new Random(); static void Main(string[] args) { UInt16[] U = new UInt16[UInt16.MaxValue]; //Заполнить всеми возможными значениями, кроме одного UInt16 Selected = (UInt16)random.Next(UInt16.MaxValue); Console.WriteLine("Ищем {0}", Selected); //Заполнить int index = 0; for (int u=0; u<=UInt16.MaxValue; u++) if (u != Selected) U[index++] = (UInt16)u; //Найти. Так как массив построен упорядоченным по возрастанию, то //отсутствующий элемент отличается от предыдущего на 2, а не на 1 UInt16 Found = 0; //Проверить случай: отсутствует 0 if (U[0] == 0) { for (index = 0; index < U.Length - 1; index++) if (U[index + 1] != U[index] + 1) { Found = (UInt16)(index + 1); break; } //случай: UInt16.MaxValue if (Found == 0) Found = UInt16.MaxValue; } Console.WriteLine("Найден {0}", Found); Console.ReadKey(); } } } 25 Вывод результатов на экран 26 Практическое задание 3 Задание 1 Написать единую программу на языке высокого уровня (С++, C#, Java), реализующую сортировку массива, заполненного случайными числами в диапазоне от 0 до 100, различными методами. Провести сравнительный анализ временной эффективности реализованных методов. Должны быть реализованы следующие методы сортировки: • Сортировка методом прямого обмена (сортировка методом пузырька). • Сортировка методом прямого включения. • Сортировка методом прямого выбора. • Шейкерная сортировка. • Сортировка методом Шелла. • Сортировка методом Хоара. Задание 2 Написать программу графической визуализации одного из методов сортировки. Программа using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Pr3 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } const int N = 13; 27 int[] A; int[] A0; Random random = new Random(); private void Form1_Load(object sender, EventArgs e) { comboBox.SelectedIndex = 0; for (int k=0; k< N; k++) { dgv.Columns.Add("", k.ToString()); dgv.Columns[k].Width = 50; } buttonCreate_Click(sender, e); } private void buttonCreate_Click(object sender, EventArgs e) { A0 = new int[N]; A = new int[N]; for (int k = 0; k < N; k++) A0[k] = random.Next(0, 100); dgv.Rows.Clear(); Register(A0); } void Register(int[] A, int i=-1,int j=-1) { dgv.Rows.Add(); for (int k = 0; k < A.Length; k++) dgv.Rows[dgv.RowCount - 1].Cells[k].Value = A[k]; if (i >= 0) dgv.Rows[dgv.RowCount - 1].Cells[i].Style.BackColor = Color.Yellow; if (j >= 0) dgv.Rows[dgv.RowCount - 1].Cells[j].Style.BackColor = Color.Yellow; } private void buttonSort_Click(object sender, EventArgs e) { dgv.Rows.Clear(); Array.Copy(A0, A, A.Length); Register(A); switch (comboBox.SelectedIndex) { case 0: //Сортировка методом прямого обмена (сортировка методом пузырька). BubbleSort(A); break; case 1://Сортировка методом прямого включения. InsertSort(A); break; case 2: //Сортировка методом прямого выбора. SelectSort(A); 28 break; case 3://Шейкерная сортировка. ShakerSort(A); break; case 4://Сортировка методом Шелла. ShellSort(A); break; case 5: //Сортировка методом Хоара. QuickSort(A); break; } Register(A); } void swap(int a, int b, int[] A) { int temp = A[a]; A[a] = A[b]; A[b] = temp; Register(A,a,b); } //Пузырьковая void BubbleSort(int[] a) { int Len = a.Length; for (int i = 0; i < Len - 1; i++) for (int j = 0; j < Len - i - 1; j++) if (a[j] > a[j + 1]) swap(j, j + 1,a); } //Вставками (методом прямого включения) //Суть алгоритма заключается в том что, на каждом шаге //мы берем один из элементов массива, //находим позицию для вставки и вставляем. //Массив из одного элемента считается отсортированным. void InsertSort(int[] a) { int Len = a.Length; for (int i = 1; i < Len; i++) { for (int j = i; j > 0 && a[j - 1] > a[j]; j--) { int temp = a[j - 1]; a[j - 1] = a[j]; a[j] = temp; Register(a,j-1); } } } //Выбором (Отбором) //Идея линейной сортировки по неубыванию заключается в том, 29 //чтобы, последовательно просматривая весь массив, отыскать наименьшее число //и поменять его местами с первым элементом. //Затем просматриваются элементы массива, начиная со второго, //снова находится наименьший, который меняется местами со вторым и т.д. void SelectSort(int[] a) { int Len = a.Length; for (int k = 0; k < Len - 1; k++) { int best = k; for (int i = k + 1; i < Len; i++) { if (a[i] < a[best]) best = i; } if (best != k) swap(k,best,a); } } //Шелла void ShellSort(int[] a) { int Len = a.Length; for (int s = Len / 2; s > 0; s /= 2) { for (int i = 0; i < Len; i++) { for (int j = i + s; j < Len; j += s) { if (a[i] > a[j]) swap(j, i, a); } } } } //Перемешиванием (Шейкер) void ShakerSort(int[] a) { int Len = a.Length; //Длина массива int left = 0; int right = Len - 1; bool flag = true; while (left <= right && flag) { flag = false; for (int i = left; i < right; i++) { 30 if (A[i] > A[i + 1]) { swap(i, i + 1,a); flag = true; } } right--; for (int i = right; i > left; i--) { if (A[i] < A[i - 1]) { swap(i, i - 1,a); flag = true; } } left++; } } //Быстрая сортировка (Хоара) //Выбрать из массива элемент, называемый опорным. //Сравнить все остальные элементы с опорным и переставить их в массиве так, чтобы разбить массив на две части //Для отрезков «меньших» и «больших» значений выполнить рекурсивно ту же последовательность операций void quickSort(int [] a, int left, int right) { int i = left, j = right; //опорный элемент - из середины int m = a[(left + right) / 2]; while (i <= j) { while (a[i] < m) { i++; } while (a[j] > m) { j--; } if (i <= j) { if (a[i] != a[j]) { swap(i,j,a); } i++; j--; } }; 31 //Рекурсивный вызов if (left < j) quickSort(a, left, j); if (i < right) quickSort(a, i, right); } void QuickSort(int[] a) { int Len = a.Length; quickSort(a, 0, Len - 1); } } } 32 Вывод результатов на экран 33 34 35 Практическое задание 4 Задание 1 Написать программу на языке высокого уровня (С++, C#, Java), реализующую поиск заданного элемента в неупорядоченном массиве. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr4_1 { class Program { static void Print(int[] array, string Header) { Console.Write(Header); for (int i = 0; i < array.Length; i++) Console.Write("{0,4} ", array[i].ToString()); Console.WriteLine(); } static Random random = new Random(); static int[] Create(int size, int min, int max) { int[] result = new int[size]; for (int i = 0; i < size; i++) result[i] = random.Next(min,max); return result; } static int IndexOf(int value, int[] array) { for (int k = 0; k < array.Length; k++) if (array[k] == value) return k; return -1; } static void Main(string[] args) { int[] A = Create(10, 0, 9); Print(A,"A = "); for (int x = -1; x < 10; x++) { Console.Write("x={0} ", x); 36 int found = IndexOf(x, A); if (found>=0) Console.Write(" index = {0}", found); else Console.Write("не найден"); Console.WriteLine(); } Console.ReadKey(); } } } Вывод результатов на экран 37 Задание 2 Написать программу на языке высокого уровня (С++, C#, Java), реализующую поиск подстроки в строке. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr4_2 { class Program { static void Main(string[] args) { Console.Write("Введите строку : "); string s = Console.ReadLine(); Console.Write("Введите подстроку : "); string subs = Console.ReadLine(); int found = IndexOf(s, subs); if (found>=0) Console.WriteLine("Подстрока начинается с позиции {0}", found); else Console.WriteLine("Подстрока не найдена"); Console.ReadKey(); } static int IndexOf(string str, string substr) { for (int result = 0; result < str.Length - substr.Length+1; result++) if (str.Substring(result, substr.Length) == substr) return result; return -1; } } } Вывод результатов на экран 38 Практическое задание 5 Задание 1 Написать программу на языке высокого уровня (С++, C#, Java), реализующую стек на базе списка. Программа using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pr5s { //Реализован класс "Стек" class Stack { class Element { public int value; public Element next = null; } Element top = null; public void Push(int value) { Element e = new Element() { value = value, next = top }; top = e; } public int Peek() { return top.value; } public int Pop() { int result = Peek(); top = top.next; return result; } public bool Empty() { return top == null; } public void Print() 39 { Element e = top; while (e != null) { Console.Write("{0} ", e.value); e = e.next; } Console.WriteLine(); } } class Program { static void Main(string[] args) { Stack S = new Stack(); Random random = new Random(); for (int k = 0; k < 10; k++) S.Push(random.Next(0, 10)); Console.WriteLine("Исходный стек"); S.Print(); Console.WriteLine("Извлекаем"); while (!S.Empty()) Console.WriteLine(S.Pop()); Console.ReadKey(); } } } Вывод результатов на экран 40