- •Ответы по дисциплине «Основы алгоритмизации и программирования»
- •Запись алгоритма Евклида на языке с
- •Int main() {
- •Эвристический алгоритм «ближайшего соседа»
- •Эвристический алгоритм «ближайших пар»
- •«Правильный» алгоритм поиска маршрута
- •Эволюция языка с bcpl → b → c → k&r c → ansi c → c99 → c1x
- •#Define имя текст_для_подстановки
- •123, 67543, 037, 07777, 0Xabf7, 0xffff, …
- •123456789L, 0xful (это просто число 15).
- •Определение символических констант в limits.H
- •Int lower, upper, step;
- •Int main() {
- •Int main() {
- •Int main() {
- •Всего операций: 47
- •If (условие) оператор
- •If (условие) оператор1 else оператор2
- •Int main() {
- •Int main() {
- •Int main() {
- •Int main() {
- •If (found)
- •Адресация памяти
- •Адреса объектов программы
- •Int fact(int n) {
- •О размерах участков памяти, выделяемых объектам
- •Правила адресной арифметики
- •Никакие другие операции к адресам неприменимы, т.Е. Адреса нельзя умножать, делить, складывать между собой и пр.
- •Имя массива – это константный указатель на его начало.
- •T X[] эквивалентно t *X
- •Int main() {
- •Void *calloc(size_t n, size_t r)
- •Void free(void *p)
- •Int main() {
- •Void *p;
- •Void swaps(char** a, char** b) {
- •Int main(void) {
- •Int main() {
- •Правило «право-лево»
- •Int pt_in_rect(struct point p, struct rect r) {
- •Int main() {
- •Int main() {
- •Int ival;
- •Void init(Vector*);
- •Void resize(Vector*, int);
- •Void push_back(Vector*, double);
- •Void push_s(Stack *st, double d) {
- •Void init_q(Queue *q) {
- •Void enqueue(Queue *q, double d) {
- •Int dequeue(Queue *q, double *d) {
- •Typedef struct Heap {Vector V;} Heap;
- •Void init_h(Heap *hp) {
- •Int Heap_Maximum(Heap *hp, double *z) {
- •Void Max_Heap_Insert(Heap *hp, double X){
- •Void Max_Heapify(Heap *hp, int I) {
- •Int l, r, largest;
- •Int Heap_Extract_Max(Heap *hp, double *z) {
- •Void Build_Max_Heap(Heap *hp) {
- •Void Insert_head_l1(List1 *l, double z) {
- •Void Insert_back_l1(List1 *l, double z) {
- •Int Extract_head_l1(List1 *l, double *z) {
- •Int Extract_back_l1(List1 *l, double *z) {
- •Void reverse_l1(List1 *l) {
- •Исходный код функции sort_l1
- •Void sort_l1(List1 *l) {
- •Void visit(List1* l) {
- •Void traverse(List1* l) {
- •Void Print_l1(List1 *l) {
- •Void Insert_l2(List2 *l, double z, int direction) {
- •Прямой обход (сверху вниз), при котором мы посещаем узел, а затем левое и правое поддеревья
- •Поперечный обход (слева направо), при котором мы посещаем левое поддерево, затем узел, а затем правое поддерево
- •Обратный обход (снизу вверх), при котором мы посещаем левое и правое поддеревья, а затем узел.
- •Простой метод сортировки массива
- •Задача о взвешивании монет
- •1) Очевидно, что на последнем шаге процедуры взвешивания мы должны иметь дело максимум с 3 монетами, чтобы в при любом исходе взвешивания получить результат.
- •2) Задача предпоследнего шага – отобрать группу из 3-х монет. Это можно сделать, если в нашем распоряжении будет не более 9 монет (3 группы по 3 монеты).
- •3) Наконец, если у нас будет от 10 до 27 монет, мы сможем отобрать из них не более 9
- •Void mov(int n, char a, char c, char b) {
- •Int main() {
Void init_h(Heap *hp) {
init(&hp->v);
}
Функция получения максимального элемента Heap_Maximum также тривиальна, т.к. максимальный элемент всегда находится в начале массива:
Int Heap_Maximum(Heap *hp, double *z) {
if(hp->v.sz == 0) return 0; // если пирамида пуста
*z = hp->v.elem[0]; return 1;
}
Практический интерес представляют еще две операции над пирамидой:
включение в пирамиду нового элемента Max_Heap_Insert и
извлечение максимального элемента (удаление корня) Heap_Extract_Max.
Вопрос №78. Алгоритм включения в пирамиду нового элемента.
При построении алгоритмов реализации этих операций необходимо учитывать, что основное свойство пирамиды в результате их применения не должно нарушиться.
Разработаем алгоритм выполнения операции Max_Heap_Insert.
Первым шагом этого алгоритма будет включение нового элемента с помощью операции push_back для вектора, т.е. новый элемент помещается в конец массива. Рассмотрим пример:
К ак следует из рисунка, мы получили «слегка испорченную» пирамиду, один элемент которой стоит не «на месте». Очевидный алгоритм «исправления» пирамиды заключается в «подъеме» «неправильного элемента» вверх по дереву путем его сравнения и обмена местами (при необходимости) с предком.
Следующие рисунки демонстрируют алгоритм «подъема» и запись этого алгоритма на языке С - текст функции Max_Heap_Insert:
Void Max_Heap_Insert(Heap *hp, double X){
hp->v.elem[(hp->v.sz)++] = x; // помещаем в конец массива
int i;
for(i = hp->v.sz-1; i > 0; i = (i-1)/2) { // «подъем»
if(hp->v.elem[(i-1)/2] > hp->v.elem[i]) return;
swapv(&hp->v, i, (i-1)/2); // обмен с предком
}
}
Вопрос №79. Алгоритм извлечения из пирамиды максимального элемента (удаление корня).
Разработаем алгоритм выполнения операции Heap_Extract_Max.
Рассмотрим пирамиду:
На первом шаге для удалению корня выполним две операции: переместим последний элемент в корень, а затем уменьшим на 1 счетчик количества элементов (т.е. переменную sz - размер вектора).
В результате также получим «слегка испорченную» пирамиду, один элемент которой (корень) стоит не «на месте». Очевидный алгоритм «исправления» пирамиды заключается в «спуске» «неправильного элемента» вниз по дереву путем его сравнения и обмена местами (при необходимости) с потомками.
Следующие рисунки демонстрируют алгоритм «спуска»:
Ниже приведён текст вспомогательной функции Max_Heapify, которая реализует алгоритм спуска «неправильного» элемента пирамиды с индексом i при условии, что левое и правое поддерево узла i обладают основным свойством пирамиды.
Void Max_Heapify(Heap *hp, int I) {
Int l, r, largest;
l = i*2+1; r = l+1; // индексы потомков слева и справа
if ((l < hp->v.sz) && (hp->v.elem[l] > hp->v.elem[i]))
largest = l;
else largest = i;
if ((r < hp->v.sz) && (hp->v.elem[r] > hp->v.elem[largest]))
largest = r;
if (largest != i) { // если один из потомков больше узла i
swapv(&hp->v, i, largest); // меняем местами
Max_Heapify(hp, largest); // рекурсивный вызов
}
}
С использованием функции Max_Heapify текст функции удаления вершины пирамиды Heap_Extract_Max будет выглядеть так: