Графический интерфейс Windows
Для создания работы с графикой в C# необходимо создать приложение Windows
После создания проекта на экране появится Форма (Form1) и Панель Элементов. Визуальным способом добавим на форму объекты Button - кнопка, PictureBox - поле для рисования.
В окне "Свойства" объекта Button1 необходимо нажать кнопку "События" , найти событие "Click" и дважды щелкнуть по ней мышью. В результате откроется модуль формы Form1.cs с созданным методом обработки события:
private void button1_Click(object sender, EventArgs e)
{
}
В языке C# существует библиотека для работы с графикой System.Drawing. Она автоматически подключается при создании проекта Windows Form Application.
Далее, на поле pictureBox1 можно нарисовать прямоугольник и простые линии:
private void button1_Click(object sender, EventArgs e)
{
//Выбираем перо "myPen" черного цвета Black
//толщиной в 1 пиксель
Pen myPen = new Pen(Color.Black, 1);
//Объявляем объект "g" класса Graphics и предоставляем
//ему возможность рисования на pictureBox1
Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
// Рисуем прямоугольник и его диагонали
g.DrawRectangle(myPen, 10, 10, 50, 50);
g.DrawLine(myPen, 10, 10, 60, 60);
g.DrawLine(myPen, 10, 60, 60, 10);
}
В следующем примере кода демонстрируется создание объекта Pen с помощью Brush и влияние задания LineJoin Свойства на Pen, а также заливка фигуры.
private void button1_Click(object sender, EventArgs e)
{
// Создаем еще 1 перо, для задания цвета используем кисть Brushes
Pen skyBluePen = new Pen(Brushes.DeepSkyBlue);
// Задаем толщину в пикселях
skyBluePen.Width = 8.0F;
// Задаем стиль завершения линий типа "скос"
skyBluePen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;
Graphics g1 = Graphics.FromHwnd(pictureBox1.Handle);
// Рисуем прямоугольник посредством передачи объекта Rectangle
Rectangle r = new Rectangle(70, 70, 50, 40);
g1.DrawRectangle(skyBluePen, r);
// Заливаем его зеленым цветом
g1.FillRectangle(Brushes.Green, r);
// Удалаем кисть
skyBluePen.Dispose();
}
Работа с текстом осуществляется посредством метода Graphics.DrawString, а также классов Font, StringFormat и Text. Ниже представлен пример работы с текстом с разными режимами форматирования и графического отображения:
private void button1_Click(object sender, EventArgs e)
{
String drawString = "Hello World";
// Задаем параметры font and brush.
Font drawFont = new Font("Arial", 16);
SolidBrush drawBrush = new SolidBrush(Color.Black);
// задаем координаты верхнего левого угла вывода текста
float x = 300.0F;
float y = 30.0F;
// Форматируем текст с выравниванием по вертикали
StringFormat drawFormat = new StringFormat();
drawFormat.FormatFlags = StringFormatFlags.DirectionVertical;
// Выводим текст заданным шрифтом, цветом и форматом от указанных координат
g.DrawString(drawString, drawFont, drawBrush, x, y, drawFormat);
// Задаем шрифт GenericSansSerif размером 20 пикселей, стандартный текст
Font myFont = new Font(FontFamily.GenericSansSerif, 20, FontStyle.Regular);
// Задаем режим визуализации текста с помощью базовых знаков
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SingleBitPerPixel;
// Выводим текст заданным шрифтом и цветом Firebrick от указанных координат
g.DrawString(drawString, myFont, Brushes.Firebrick, 140.0F, 20.0F);
// Задаем режим визуализации текста с помощью сглаженных базовых знаков
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
g.DrawString(drawString, myFont, Brushes.Firebrick, 140.0F, 60.0F);
// Задаем высокий текстовый контраст
g.TextContrast = 0;
g.DrawString(drawString, myFont, Brushes.DodgerBlue, 140.0F, 100.0F);
// Задаем низкий текстовый контраст
g.TextContrast = 12;
g.DrawString(drawString, myFont, Brushes.DodgerBlue, 140.0F, 140.0F);
Более подробно см. документацию: https://docs.microsoft.com/ru-ru/dotnet/api/system.drawing.
Результат выполнения представленного кода:
Двоичное дерево
Двоичное дерево — древовидная структура данных, в которой каждый узел имеет не более двух потомков (детей). В такой структуре первый узел называется родительским узлом, а дети называются левым и правым потомками соответственно.
Двоичное дерево поиска (binary search tree, BST) — это двоичное дерево, для которого выполняются следующие условия:
- Оба поддерева — левое и правое, являются двоичными деревьями поиска.
- У всех узлов левого поддерева произвольного узла «A» значения ключей меньше, нежели значение ключа самого узла «A».
- В то время, как у всех узлов правого поддерева того же узла «A» значения ключей не меньше, нежели значение ключа узла «A».
- Очевидно, данные в каждом узле должны обладать ключами, для которых определена операция сравнения.
Двоичное дерево поиска можно определить так:
- Каждое новое поддерево (левое и правое) являются двоичными деревьями поиска.
- У всех узлов левого поддерева значения ключей меньше, чем значение ключа элемента родителя.
- У всех узлов правого поддерева значения ключей не меньше, чем значения ключа родительского узла.
Основным преимуществом двоичного дерева поиска перед другими структурами данных является высокая эффективность реализации основанных на нём алгоритмов поиска и сортировки.
Реализация двоичного дерева поиска начинается с задания узла, который содержит ссылки на свой левый и правый потомок, если они у него есть. При добавлении нового узла в дерево, его значение сравнивается с помощью метода IComparable.CompareTo со значением родительского элемента, что бы определить правый это потомок или левый.
class BinaryTreeNode<TNode> : IComparable<TNode> where TNode : IComparable<TNode>
{
public BinaryTreeNode<TNode> Left { get; set; }
public BinaryTreeNode<TNode> Right { get; set; }
public int CompareTo(TNode other)
{
return this.CompareTo(other);
}
}
Метод добавления нового узла в дерево:
Алгоритм добавления нового узла в дерево не сложен и значительно упрощается с применением рекурсии. Если дерево не содержит узлов (пустое), то новое значение становится корнем нового дерева. Если дерево не пустое, то мы сравниваем значение нового узла со значением корня дерева, если новое значение больше, то алгоритм повторяется для правого потомка, если меньше то для левого.
public class BinaryTree<T> : IEnumerable<T> where T : IComparable<T>
{
public void Add(T value)
{
//
}
}
Метод поиска узла:
Поиск узла в дереве начинается с его корня (метод FindWithParent) и предполагает следующие шаги:
- Если значения текущего узла null — закончить поиск и вернуть null.
- Если значения текущего узла равно искомому, результатом поиска будет текущие значение узла.
- Если искомое значение меньше чем текущие, нужно перейти к левому потомку и повторить алгоритм с первого пункта.
- Если значение больше или равно текущему, нужно перейти к правому потомку и повторить алгоритм с первого пункта.
Метод Contains() основывается на методе поиска и определяет принадлежит ли указанный элемент дереву или нет, если да то он возвращает true, в противном случае false.
Удаления узла дерева:
При удалении узла из дерева нужно учитывать три возможных варианта:
- Первый вариант: удаляемый узел не имеет правого потомка.
- Второй вариант: удаляемый узел имеет правого потомка, у которого нет левого потомка.
- Третий вариант: удаляемый узел имеет правого потомка, у которого есть левый потомок.
1. Если удаляемый узел(5) не имеет правого потомка, то достаточно переместить на его место левого потомка(2).
2. Если удаляемый узел(5) имеет правого потомка(6), у которого в свою очередь, тоже есть правый потомок(7), то достаточно переместить их с соблюдением иерархии.
3. Если удаляемый узел (5) имеет правого потомка (7), у которого в свою очередь есть левый потомок(6), то крайний левый потомок узла (7) должен быть перемещен на место удаляемого узла.
Алгоритм обхода
Алгоритм обхода двоичного дерева предусматривает обход всех вершин дерева только один раз. Существуют три вида таких обходов:
1. Прямой порядок (англ. preorder), посещение узлов родителей до посещения узлов потомков:
- Зайти в корень.
- Зайти в левое поддерево.
- Зайти в правое поддерево.
2. Обратный порядок (англ. postorder), посещение узлов потомков до посещения узлов их родителей:
- Зайти в левое поддерево.
- Зайти в правое поддерево.
- Зайти в корень.
3. Симметричный порядок(англ. inorder):
- Зайти в левое поддерево.
- Зайти в корень.
- Зайти в правое поддерево.
Прямой порядок
Порядок следования при прямом обходе дерева: 4, 2, 1, 3, 5, 7, 6, 8
Обратный порядок
Порядок следования при обратном обходе дерева: 1, 3, 2, 6, 8, 7, 5, 4
Дата добавления: 2021-12-14; просмотров: 370;