Лекция 21: Программы на языке С при использовании статически подключаемой библиотеки
Задание 1
- К проекту подключите статическую библиотеку с файлами xyx.h, xyx.c. Осуществите сборку проекта из приведенных файлов.
- Предусмотрите ввод чисел массива с клавиатуры.
- Напишите функцию типа xyx(), которая обрабатывает одномерные символьные массивы данных.
- Видоизмените программу для преобразования массива с действительными числами, которые формируются случайным образом из данного интервала [–2*X;2*X], где Х – номер компьютера, на котором выполняется лабораторная работа.
- Разработайте функцию сортировки чисел массива, поместите ее в статическую библиотеку, и используйте для сортировки заданного массива по убыванию в соответствии с предыдущим пунктом задания. После сортировки произведите преобразование массива с помощью созданной библиотечной функции xyx().
Пример 2. Разработайте абстрактный тип данных – двоичное дерево поиска. Выполните вставки узлов в двоичное дерево случайными числами и произведите обход дерева с порядковой выборкой [20.2]. Созданные функции заполнения и обхода двоичного дерева поместите в статическую библиотеку.
Дерево – это нелинейная двухмерная структура данных с особыми свойствами. Узлы дерева две или более связей. В двоичном дереве узлы содержат две связки. Первый узел дерева называется корневым. Каждая связь корневого узла ссылается на потомка. Левый потомок – первый узел левого поддерева, правый потомок – первый узел правого поддерева. Потомки одного узла называются узлами-сиблингами. Узел, не имеющий потомков, называется листом.
Двоичное дерево поиска (с неповторяющимися значениями в узлах) устроено так, что значения в любом левом поддереве меньше, чем значение в родительском узле, а значения в любом правом поддереве больше, чем значение в родительском узле [20.2]. На рис. 20.18 изображена схема двоичного дерева поиска с 12 значениями.
В программах, реализующих стеки, очереди, деревья и т.д., используются автореферентные структуры ( self-referential ), которые содержат в качестве элемента указатель, который ссылается на структуру того же типа.
struct node { int data; struct node *nextPtr; };
описывает тип struct node. Элемент nextPtr указывает на структуру типа struct node – структуру того же самого типа, что и объявленная структура, т.е. ссылается сама на себя.
Для заданного примера используем целые случайные числа из интервала от 0 до 14.
Программный код решения примера, состоящий из трех файлов:
// Файл основного модуля проекта main.c #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <time.h> #include <locale.h> //#include "tree.h" #define N 10 // количество случайных чисел - узлов #define R 15 // случайные числа от 0 до R-1 // Автореферентная структура struct treeNode { struct treeNode *LeftPtr; //для левого поддерева int data; struct treeNode *RightPtr; // для правого поддерева }; typedef struct treeNode TreeNode; typedef TreeNode *TreeNodePtr; // Прототипы функций void insertNode (TreeNodePtr *treePtr, int value); void inOrder(TreeNodePtr treePtr); int main (void) { int i; int item; time_t tic; TreeNodePtr rootPtr = NULL; // пустое дерево setlocale(LC_ALL, ".1251"); // русские шрифты srand((unsigned) time(&tic)); // рандомизация случайных чисел printf("\n Числа двоичного дерева:\n"); // Размещение в дереве случайных значений от 0 до (R-1) for (i = 1; i <= N; ++i) { item = rand() % R; printf(" %4d", item); insertNode (&rootPtr, item); } // Обход дерева с порядковой выборкой printf("\n"); printf("\n Результат обхода дерева с порядковой выборкой:\n"); inOrder(rootPtr); // вызов функции printf("\n\n Нажмите любую клавишу (Press any key): "); _getch(); return 0; }
// Функция insertNode() // Вставка узла в дерево void insertNode (TreeNodePtr *treePtr, int value) { if (*treePtr == NULL) { *treePtr = malloc(sizeof(TreeNode)); // присвоение данных if (*treePtr != NULL) { (*treePtr)->data = value; (*treePtr)->LeftPtr = NULL; (*treePtr)->RightPtr = NULL; } else { printf(" %d не вставлено. Нет памяти.\n", value); } } else { //когда дерево не пусто if ( value < (*treePtr)->data ) insertNode (&( (*treePtr)->LeftPtr), value); else if( value > (*treePtr)->data ) insertNode (&( (*treePtr)->RightPtr), value); else printf("Дубл."); // Дубликаты значений в узлах дерева } }
// Функция inOrder() // Обход дерева с порядковой выборкой void inOrder (TreeNodePtr treePtr) { if (treePtr != NULL) { inOrder(treePtr->LeftPtr); printf(" %4d", treePtr->data); inOrder(treePtr->RightPtr); } }
Функции insertNode(), inOrder() используются рекурсивно, т.е. они вызывают сами себя из тела функции.
В теле функции inOrder() выполняются следующие шаги:
- Обойти вызовом inOrder() левое поддерево.
- Обработать значение в узле.
- Обойти вызовом inOrder() правое поддерево.
Обход двоичного дерева поиска вызовом функции inOrder() выдает значения в узлах в возрастающем порядке. Процесс создания двоичного дерева поиска фактически сортирует данные, поэтому называется сортировкой двоичного дерева [20.2].
Возможный результат работы программы показан на рис. 20.10.
Задание 2
- Функции заполнения и обхода двоичного дерева поместите в статическую библиотеку. Выполните настройки проекта с подключаемой статической библиотекой.
- Напишите программу с использованием вещественных чисел, помещаемых в узлы двоичного дерева. Случайные числа (значения узлов дерева) задайте из интервала [–2*X;2*X], где Х – номер компьютера, на котором выполняется лабораторная работа.
- Увеличьте число узлов дерева до 11*Х, где Х – номер компьютера, на котором выполняется лабораторная работа. Результат выполнения программы запишите в текстовый файл вида treeX.txt, где Х – первая буква фамилии пользователя.
Контрольные вопросы
- Какая библиотека называется статически подключаемой?
- Какую нотацию рекомендуется использовать для созданных пользователем библиотечных модулей?
- Какое расширение используется для созданных пользовательских библиотечных модулей?
- Применяется или нет функция main() в статически подключаемой библиотеке, созданной пользователем?
- По какой дисциплине происходит обработка данных в такой структуре данных, как стек?
- По какой дисциплине происходит обработка данных в такой структуре данных, как очередь?