26. 11. 2017 Списки та рекурсія Рекурсія —

Скачать презентацию 26. 11. 2017 Списки та рекурсія Рекурсія — Скачать презентацию 26. 11. 2017 Списки та рекурсія Рекурсія —

lst_rec.ppt

  • Количество слайдов: 22

>26.11.2017 Списки та рекурсія Рекурсія — це не щось надскладне, а просто ще один 26.11.2017 Списки та рекурсія Рекурсія — це не щось надскладне, а просто ще один засіб програмування, яким можна користуватися успішно або зловживати, як і всім іншим. Д. Баррон

>Списки та рекурсія Список елементів множини A : порожній список < > - є Списки та рекурсія Список елементів множини A : порожній список < > - є списком; - список, то > - також є списком. Потрібні типи даних можна визначити, наприклад, так: typedef struct Node {int dat; Node *next;} Listn, *Listp;

>Списки та рекурсія Розглянемо приклади рекурсивних та ітеративних функцій для обробки зв`язного представлення списків. Списки та рекурсія Розглянемо приклади рекурсивних та ітеративних функцій для обробки зв`язного представлення списків.

>Представлення даних typedef struct Node {int dat; Node *next;} Listn, *Listp; !!! Не єдиний Представлення даних typedef struct Node {int dat; Node *next;} Listn, *Listp; !!! Не єдиний можливий спосіб визначити потрібні типи даних.

>Побудова списку (ітерація) //побудова списку з N елементів n, n-1, n-2,..., 2, 1 Listp Побудова списку (ітерація) //побудова списку з N елементів n, n-1, n-2,..., 2, 1 Listp lform(int n){ Listp p, t = NULL; for (int i = 1; i <= n; i++){ p = new Node; p->dat = i; p->next = t; t = p; } return p;}

>Побудова списку (рекурсія) //побудова списку з N елементів n, n-1, n-2,..., 2, 1 Listp Побудова списку (рекурсія) //побудова списку з N елементів n, n-1, n-2,..., 2, 1 Listp lform_r(int n){ if (n){ Listp p = new Node; p->dat = n; p->next = lform_r(n-1); return p; } return NULL; }

>Відображення списку (ітерація) //виведення списку void lprint(Listp p){ while (p){ cout << p->dat << Відображення списку (ітерація) //виведення списку void lprint(Listp p){ while (p){ cout << p->dat << ' '; p = p->next; } cout << endl; }

>Відображення списку (рекурсія) //рекурсивне виведення списку void lprint_r(Listp p){ if (p){ cout << p->dat Відображення списку (рекурсія) //рекурсивне виведення списку void lprint_r(Listp p){ if (p){ cout << p->dat << ' '; lprint_r(p->next); } } //cout << endl; ???

>Вилучення списку (ітерація) //знищення списку void ldel(Listp p){ Listp t; while (p){ t = Вилучення списку (ітерація) //знищення списку void ldel(Listp p){ Listp t; while (p){ t = p; p = p->next; delete t; } }

>Вилучення списку (рекурсія) //рекурсивне знищення списку void ldel_r(Listp p){ if (p){ ldel_r(p->next); delete p; Вилучення списку (рекурсія) //рекурсивне знищення списку void ldel_r(Listp p){ if (p){ ldel_r(p->next); delete p; } }

>Кількість елементів списку (ітерація) //кількість елементів списку int numb(Listp p){ int n = 0; Кількість елементів списку (ітерація) //кількість елементів списку int numb(Listp p){ int n = 0; while (p){ n++; p = p->next; } return n; }

>Кількість елементів списку (рекурсія) //рекурсивно кількість елементів списку int numb_r(Listp p){ if (p) return Кількість елементів списку (рекурсія) //рекурсивно кількість елементів списку int numb_r(Listp p){ if (p) return (1 + numb_r(p->next)); return 0; }

>Пошук у списку (ітерація) //пошук елемента за ключем Listp find(Listp const pbeg, int d){ Пошук у списку (ітерація) //пошук елемента за ключем Listp find(Listp const pbeg, int d){ Listp t = pbeg; while (t){ if (t->dat == d) break; t = t->next; } return t; }

>Пошук у списку (рекурсія) //рекурсивний пошук елемента за ключем Listp find_r(Listp const pbeg, int Пошук у списку (рекурсія) //рекурсивний пошук елемента за ключем Listp find_r(Listp const pbeg, int d){ if (pbeg) { if (pbeg->dat == d) return pbeg; else return(find_r(pbeg->next, d)); } else return(pbeg); }

>Списки та рекурсія Порівняємо наведені рішення: ??? “телефонна аналогія” Списки та рекурсія Порівняємо наведені рішення: ??? “телефонна аналогія”

>Зауваження Розглянули один із способів зв`язного представлення списків - лінійні “однозв`язні” списки - зберігаються Зауваження Розглянули один із способів зв`язного представлення списків - лінійні “однозв`язні” списки - зберігаються зв`язки поточного елемента з наступним. Існують інші способи організації елементів списку (“двозв`язні”, “циклічні”, “з головою”, з інформацією в елементах, або ззовні елементів, а також комбінація вказаних). Обрання способу організації елементів списку повинно враховувати потрібні дії зі списком.

>Підсумки Розглянуті лінійні “однозв`язні” списки надають можливості для гнучкого представлення та ефективної обробки різноманітних Підсумки Розглянуті лінійні “однозв`язні” списки надають можливості для гнучкого представлення та ефективної обробки різноманітних послідовностей даних. Розглянули найпростіші дії зі списком з використанням як ітеративного, так й рекурсивного підходу. Аналогічним чином можна було б реалізувати й інші дії зі списком, а також при іншій організації списку.

>Поради Обирати найбільш адекватний спосіб збереження для списку. Писати “прозорі”, добре структуровані програми. Здійснювати Поради Обирати найбільш адекватний спосіб збереження для списку. Писати “прозорі”, добре структуровані програми. Здійснювати внутрішнє документування у програмі за допомогою коментарів. Не зловживати “трюкачеством”. Не зловживати рекурсією. Розумним чином “форматувати” текст програми.

>Задачі Написати функції для визначення кількості додатних чисел у елементах списку: нерекурсивну; рекурсивну. Написати Задачі Написати функції для визначення кількості додатних чисел у елементах списку: нерекурсивну; рекурсивну. Написати функції розташування елементів нециклічного однозв’зного списку у зворотному порядку (обернення списку): у новому списку; без побудови нового списку.

>Задачі Написати рекурсивні функції для виконання розглянутих операцій зі списками: виведення елементів списку (розглянути Задачі Написати рекурсивні функції для виконання розглянутих операцій зі списками: виведення елементів списку (розглянути порядок: починаючи з початку, з кінця списку); додавання в кінець; додавання в середину списку. Написати рекурсивну та нерекурсивну функції для визначення суми елементів числової послідовності, представленої зв`язним списком.

>Задачі Написати функції додавання та вилучення рядка зі списку за умови, що елемент списку Задачі Написати функції додавання та вилучення рядка зі списку за умови, що елемент списку зберігає вказівник на рядок і кількість m його повторень. При першому додаванні рядка полю m присвоюється 1, потім m збільшується на 1 при додаванні і зменшується на 1 при вилученні, а при вилученні рядка з m = 1 знищується елемент, що подає рядок.

>Задачі Гра - “лічилка” задається натуральними N і M. Числа 1, …, N розташовано Задачі Гра - “лічилка” задається натуральними N і M. Числа 1, …, N розташовано колом, і від числа 1 починається відлік; M-е число вилучається. Відлік поновлюється з елемента, наступного за вилученим, і так до вилучення всіх чисел. Написати підпрограму друку за N і M послідовності чисел, які вилучаються, наприклад, при N = 4 і M = 3 це буде 3, 2, 4, 1. Пропонується реалізувати рішення з використан-ням зв’зного списку, масиву, рекурентного співвідношення.