- •1. Типы структур данных
- •2. Стек
- •Void stack::Push(int NewElement){
- •Int stack::Pop(){
- •If(!Empty){
- •2.1. Применения стека
- •2.1.1. Программный стек
- •Void main(void){
- •2.1.2.1. Обход шахматной доски ходом коня
- •Int I,j; // координаты клетки
- •Int move; // номер хода, которым покидаем клетку
- •Int I,j; // текущие координаты клетки
- •Int V; // указатель стека
- •Int BegMove,k,i2,j2;
- •2.1.2. Реализация рекурсии
- •If(Move(n,I,j,k,&i2,&j2) && !Board[i2][j2]){
- •If(Good){
- •2.1.2.1. Вычисление определенного интеграла
- •Interval Stack[maxstack];
- •2.1.3. Польская инверсная запись (полиз)
- •If(isalpha(z)) return 'б'; // буква – операнд
- •Int Poliz(char *in,char *out){
- •2.1.4. Вычисление выражения, представленного в полиз
- •Контрольные вопросы
- •3. Очередь
- •Контрольные вопросы
- •4. Массивы
- •4.1. Размещение прямоугольных массивов в последовательной памяти
- •4.2. Метод Айлиффа
- •Контрольные вопросы
- •5. Списочные структуры
- •5.1. Односвязный линейный список
- •5.1.1. Представление односвязного списка
- •5.1.2. Операции над односвязным списком
- •!!!!!!5.1.3. Голова списка
- •5.1.4 Циклический список
- •5.1.5. Пример. Сложение многочленов
- •Int px,py,pz; // степени X,y,z
- •Int PowerCmp(node *p, node *q){
- •Void PoliAdd(node *p, node *q){
- •5.2. Двусвязный линейный список
- •Void DeleteUzel(uzel *p){
- •5.3. Ортогональные списки
- •Int Row,Col; // строка и столбец элемента
- •5.4. Списки общего вида
- •5.4.1. Пример. Топологическая сортировка.
- •Int count; // счетчик числа элементов, предшествующих
- •Void TopSort(pair *p, int n_pair, file *result){
- •Void AddToTail(mains *head, mains *V){
- •5.5. Стек свободного пространства
- •Void DeleteNode(node *p, node *s){
- •5.6. Обслуживание свободного пространства
- •5.6.1. Счетчик ссылок
- •5.6.2. Сбор мусора
- •Контрольные вопросы
- •6. Множества
- •Int nElem; // число элементов в множестве
- •Int Elem[maxsize]; // элементы множества
- •Int Element; // номер элемента множества
- •Void Delete(node *p); // удаление узла вслед за p
- •Void setinlist::Delete(node *p){
- •Контрольные вопросы
- •7. Деревья
- •7.1. Бинарные деревья
- •7.2. Обход бинарного дерева
- •Void DirectByPass(node *Root){
- •Void InverseByPass(node *Root){
- •Int Tag; // может принимать значения operation или number
- •7.3. Прошитые деревья
- •Void InverseBypass(node *Root){
- •7.4. Другие представления бинарных деревьев
- •7.5. Представление деревьев общего вида
- •Int nSon; // действительное число сыновей узла
- •7.5.1. Представление деревьев общего вида бинарными деревьями
- •Контрольные вопросы
- •8. Конечный автомат
- •Int State; // текущее состояние
- •Int Class;
- •If(!Found){
- •Контрольные вопросы
- •9. Таблицы
- •9.1. Последовательные таблицы
- •Контрольные вопросы
- •9.2. Сортированные таблицы
- •9.2.1. Алгоритмы поиска в сортированной таблице
- •9.2.1.1. Бинарный поиск (дихотомия)
- •Int BinSearch(int Key, int n, int t[]){
- •Void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int (*fcmp)(const void *a, const void *b ));
- •9.2.2. Вставка и удаление в сортированной таблице
- •9.2.3. Оценка трудоемкости сортировки !!!!!
- •9.2.4. Внутренняя сортировка
- •9.2.4.1. Сортировка подсчетом
- •Void CountSort(int n, int t[]){
- •9.2.4.2. Сортировка простым выбором
- •Void SimpleChoice(int n, int t[]){
- •9.2.4.3. Квадратичный выбор
- •9.2.4.6. Сортировка методом "пузырька"
- •Void BubbleSort(int n, int t[]){
- •9.2.4.7. Сортировка слиянием
- •9.2.4.4. Выбор из дерева
- •9.2.4.5. Сортировка простыми вставками
- •Void InsertSort(int n, int t[]){
- •Void Merge(int n, int *t, int m, int *V, int *r){
- •9.2.4.8. Сортировка фон Неймана
- •Void Join(int a[], int b[], int *left, int *right,
- •Int *kl, int *kr, int Step){
- •9.2.4.9. Сортировка Хоара (1962 г.) !!!!!
- •Int Partition(int m, int n, int t[]){
- •Void Hoar(int m, int n, int t[]){
- •Void qsort(void *base, size_t nelem, size_t width,
- •Int (*fcmp)(const void *, const void *));
- •9.2.4.10. Двоичная поразрядная сортировка
- •Int BitPart(unsigned int Left, unsigned int Right,
- •Void BitSort(unsigned int Left, unsigned int Right,
- •Void BinarySort(int n,unsigned Tab[], unsigned int keylen){
- •9.2.4.11. Цифровая поразрядная сортировка
- •Void DigitalSort(byte *t, int n, int KeyLen){
- •Int *Count;
- •Int *Pos; // позиции расстановки
- •9.2.1. Внешняя сортировка
- •9.2.1.1. Многопутевое слияние и выбор с замещением
- •9.2.1.2. Многофазное слияние
- •9.2.1.3. Фибоначчиево слияние
- •9.2.1.4. Каскадное слияние
- •9.2.1.5. Сортировка в одном файле
- •Контрольные вопросы
- •9.3. Древовидные таблицы
- •Void *Record; // указатель на запись таблицы
- •Int WhatSon; // каким сыном устанавливать новую запись –
- •Int CmpKeys; // результат сравнения ключей
- •Int Info;
- •Int Rank; // для доступа по индексу
- •9.3.1. Оценка трудоемкости поиска в случайном дереве
- •9.3.2. Оптимальные деревья
- •Int Info;
- •9.3.3. Сбалансированные деревья
- •9.3.4.1. Поддержание балансировки
- •9.3.5. Представление линейных списков деревьями
- •Int Info;
- •Int Rank;
- •Контрольные вопросы
- •9.4. Таблицы с прямым доступом
- •9.5. Рассеянные таблицы (Hash)
- •9.5.1. Анализ трудоемкости операций над рассеянной таблицей
- •Контрольные вопросы
- •Литература
- •454091, Г.Челябинск, ул.Свободы, 155/1
Void *bsearch(const void *key, const void *base, size_t nelem, size_t width, int (*fcmp)(const void *a, const void *b ));
Аргументы:
key – адрес записи, имеющей структуру такую же, как и запись таблицы. В этой записи заполнены только поля, составляющие ключ.
base – адрес начала таблицы
nelem – число записей в таблице
width – длина записи в байтах
fcmp – функция, определяемая пользователем, которая сравнивает ключи записей, имеющих адреса a и b и возвращает –1 (*a<*b), 0(*a==*b) и 1(*a>*b).
Функция bsearch возвращает адрес найденной записи или NULL.
Для поиска в сортированной таблице могут быть использованы любые методы решения уравнения Ключ=F(Адрес), в частности метод золотого сечения и интерполяционные методы.
9.2.2. Вставка и удаление в сортированной таблице
П
ри
вставке новой записи в сортированной
таблице, требуется найти место в которое
её следует поместить (время ~
)
и сдвинуть все записи от места вставки
и ниже на одну позицию вниз. Аналогично,
при удалении требуется найти удаляемую
запись и все записи ниже удаляемой
сдвинуть на одну позицию вверх. Обе
операции требуют физического перемещения
в среднем
записей. Таким образом, при таком
простодушном поведении, мы проигрываем
все преимущества сортированной таблицы
для операции поиска. Поэтому при удалении
запись не удаляют физически, а лишь
помечают как удаленную в специально
отведенном байте. При вставке находят
ту позицию, в которую следовало бы
поместить новую запись, чтобы она не
нарушала порядка, но не помещают ее
туда, а помещают в линейный список,
начинающийся с позиции вставки, как на рис.31.
Рис.31. Сортированная таблица с цепочками переполнения
При поиске записи теперь следует найти позицию, в которой должна была бы находиться запись и, отправляясь от нее пройти линейный список, исходящий из этой позиции. Очевидно, что после большого количества вставок, поиск будет все больше походить на простой перебор записей. Рано или поздно, придется переписать таблицу как сортированную заново, таким образом, чтобы в ней не было удаленных позиций и цепочек переполнения. Отложенные операции обслуживания характерны для всех способов организации таблиц, кроме древовидных.
9.2.3. Оценка трудоемкости сортировки !!!!!
Оценим трудоемкость процесса упорядочения массива из N ключей. В исходном состоянии эти ключи могут образовывать любую из N! перестановок. Энтропия массива ключей, определяемая по Шеннону:
где
pi
– вероятность перестановки с номером
i.
Наибольшей энтропией обладает система,
для которой все состояния равновероятны:
.
Для упорядоченной таблицы, все ключи
которой различны, энтропия равна нулю.
Изменение энтропии равно количеству
информации, получаемой в процессе
сортировки. Для случайного массива
необходимо получить
бит информации. При сравнении ключей
Ki,
Kj
можем
получить два исхода: Ki<Kj
и Ki>Kj
.
(случаем Кi=Kj
пренебрегаем,
как маловероятным).
Если исходы равновероятны, то сравнение дает ровно 1 бит информации. Такие ключи называют статистически эквивалентными. Если исходы неравновероятны, то будет получено меньше одного бита информации. Кстати, именно из-за того, что некоторые сортировки сравнивают статистически неэквивалентные ключи, они имеют низкую эффективность. Таким образом, число сравнений ключей при сортировке удовлетворяет неравенству
Для вычисления N! воспользуемся формулой Стирлинга
С учетом этого после преобразований получим
Найденная
оценка
будет служить
ориентиром при оценке эффективности
различных методов сортировки.
