
- •Какие типы данных Вы знаете?
- •Как узнать размер типа?
- •Что такое модель памяти? Какие модели памяти Вы знаете?
- •Назовите размеры стандартных типов в используемой Вами модели памяти.
- •Что такое оператор typedef?
- •Для чего предназначена директива препроцессора #define?
- •Что такое сигнатура функции?
- •Что означает директива #include?
- •Что такое #if, #ifdef, #endif? Приведите пример применения.
- •Как можно выделить память?
- •Как можно освободить память?
- •Как проверить, что память выделилась?
- •Как создать массив на стеке? Любой ли массив можно создать на стеке?
- •Что такое "выделение памяти в куче"?
- •Что такое очередь? Как она устроена? Какие операции в ней есть?
- •Что такое куча (пирамида, Heap)?
- •2. "Двусвязный список"
- •3. Задача сортировки n объектов.
- •6. Атд "Очередь с приоритетом"
- •7. Поразрядная сортировка
- •8. Сортировка слиянием
- •9. Сортировка Шелла.
- •10. Список, стек, очередь
- •11. Быстрая сортировка-2
Как можно выделить память?
Статическое выделение памяти: пространство для объектов создаётся в области хранения данных кода программы в момент компиляции; время жизни таких объектов совпадает со временем жизни этого кода. static int arr[5];
Автоматическое выделение памяти: объекты можно временно хранить в стеке; эта память затем автоматически освобождается и может быть использована снова, после того, как программа выходит из блока, использующего её. int arr[5]; //в теле функции/метода
Динамическое выделение памяти: блоки памяти нужного размера могут запрашиваться во время выполнения программы с помощью библиотечных функций malloc, realloc и free из области памяти, называемой кучей. Эти блоки освобождаются и могут быть использованы снова после вызова для них функции free. int *arr = new int[5];
_______________________________________________________________________________
Как можно освободить память?
С помощью free(delete).
Как проверить, что память выделилась?
Пример: … int arr*; arr=(int*)malloc(ArSize*sizeof(int*)); for(i=0;i<ArSize;i++) arr=(int)malloc(ArSize*sizeof(int)); …
if(arr==0) //проверяем, выделилась ли память
альтернативный способ: if(arr==NULL)
malloc возвращает пустой указатель на выделенное пространство или NULL, если недостаточно доступной памяти.
_______________________________________________________________________________
Как создать массив на стеке? Любой ли массив можно создать на стеке?
Int arr[10];
Создали массив из 10 целочисленных элементов.
Размер массива ограничивается физической памятью компьютера.
________________________________________________________________________________
Что такое "выделение памяти в куче"?
Ку́ча — структура данных, с помощью которой реализована динамически распределяемая память приложения. Память в куче используется для размещения объектов, динамически созданных программой.
В любой момент времени существования кучи вся память, на которой работает куча, разделена на занятую и свободную. Занятая память использована под размещение объектов, уже созданных и ещё не освобождённых к этому моменту времени. Из объёма свободной памяти можно выделять память под новые объекты.
Int* p = new int[s]; - выделение памяти в куче Delete[] p; - удаление данных из кучи
______________________________________________________________________________
Как получить значение, на которое указывает указатель? Как называется эта операция?
Получить само значение переменной, на который указывает указатель, можно только выполнив операцию разыменовывания *.
int a = 3; int *p = &a; //объявили, создали, и инициализировали объект
______________________________________________________________________________
Какой тип получается при взятии адреса переменной?
&a - получение указателя (взятие адреса) тип - *тип_переменной_а (указатель на тип переменной а)
_______________________________________________________________________________
Напишите функцию swap, меняющую значения двух переменных.
Void swap (int &a, int &b) { int t=a; a=b; b=t; }
Что такое передача аргументов по ссылке и по значению?
Если мы передаем переменную по значению, то в функции используется копия этой самой переменной. Для передачи по значению пишем просто void f (int a)
Если мы передаем переменную по ссылке, то в функции мы работаем с самой переменной. Для передачи по ссылке пишем void g (int& a)
______________________________________________________________________________
Ввод-вывод¶
Какие функции для форматированного ввода из файла Вы знаете?
FILE *f; f=fopen(f"file.txt", "r"); fscanf(f, “%d”, &i); fclose(f);
_______________________________________________________________________________
Какие функции для форматированного вывода в файл Вы знаете?
FILE *f; f=fopen("file.txt", "w"); fprintf(f, “%d”, i); fclose(f);
_______________________________________________________________________________
Какие функции для форматированного чтения из стандартного потока ввода Вы знаете?
Считать из стандартного потока ввода целочисленную переменную i: C: scanf("%d", &i); C++: cin>>i;
_______________________________________________________________________________
Какие функции для форматированного вывода в стандартный поток вывода Вы знаете?
Вывести в стандартный поток вывода целочисленную переменную i: C: printf("%d", i); C++: cout<<i;
_______________________________________________________________________________
Как прочитать один символ из стандартного потока ввода?
char a=getchar(); char b=cin.get();
_______________________________________________________________________________
Как открыть файл для записи?
f=fopen("file.txt", "w");
_______________________________________________________________________________
Как закрыть файл после завершения записи?
fclose(f);
Как считать строку?
Char char_temp=getchar(); For (int i=0; char_temp!= " "; i++) {str[i]=char_temp; char_temp=getchar();}
Как вывести строку?
For (int i=0; i<len; i++) { char_temp=str[i]; printf("%c", i);}
_______________________________________________________________________________
Общее по алгоритмам¶
Какие нотации используют для обозначения сложности алгоритмов?
O(n) – где n указывает, сколько необходимо выполнить. Оценка сверху
Ө(n) – оценка сложности алгоритма с обоих сторон
_______________________________________________________________________________
Затраты каких ресурсов обычно меряют при оценке сложности?
Алгоритмы оцениваются по скорости выполнения и эффективности использования памяти
_______________________________________________________________________________
Может ли алгоритм со сложностью O(n2) работать в практической задаче быстрее, чем алгоритм со сложностью O(n lоgn)?
Может. Пример: быстрая сортировка (nlogn) и сортировка пузырьком (n2) при отсортированном массиве
_______________________________________________________________________________
Что такое рекурсия?
В программировании рекурсия — вызов функции (процедуры) из неё же самой.
_______________________________________________________________________________
Какую опасность несет рекурсия?
Наиболее очевидная опасность рекурсии заключается в бесконечной рекурсии.
Другая опасность рекурсии заключается в потерях памяти. При каждом вызове подпрограммы, система выделяет память для локальных переменных новой процедуры.
_______________________________________________________________________________
Покажите на примере, как можно избавиться от рекурсии.
n-ое число Фиббоначи можно вычислять как рекурсивным методом (с помощью рекурсии подсчитывая предыдщее число), а можно обычным циклом, считая числа Фиббоначи, начиная с первого.
_______________________________________________________________________________
Оцените сложность алгоритма поиска простых чисел.
При простом переборе делителей O(n sqrt(n) ) задача сортировки - упорядочивание элементов массива по неубыванию
Сортировки¶
В чем заключается задача сортировки?
При простом переборе делителей O(n sqrt(n) ) задача сортировки - упорядочивание элементов массива по неубыванию (или какому-то иному признаку)
_______________________________________________________________________________
Какова наименьшая сложность алгоритма сортировки?
O (n log n)
_______________________________________________________________________________
Какова сложность алгоритма сортировки пузырьком?
O(n2)
_______________________________________________________________________________
Какова сложность алгоритма сортировки пузырьком в лучшем случае?
O (n) В том случае, когда массив уже отсортирован
_______________________________________________________________________________
Какова сложность алгоритма сортировки Шелла?
Зависит от последовательности, которая используется в сортировке. В среднем O(n3/2) Последовательности и их сложность: Шелла: d1=N/2 di=di-1/2 dk=1 O(cn2) Хиббард: все (2i-1)/2 <= n/2 O(n3/2) Пратт: все 2i*3j<=n/2 O(n (log n)2 )
_______________________________________________________________________________
Какова сложность алгоритма сортировки вставками?
O(n2)
_______________________________________________________________________________
Какова сложность алгоритма быстрой сортировки?
O(n log n) в среднем, O(n2) в худшем случае
Какие оптимизации быстрой сортировки Вы знаете?
При выборе опорного элемента из данного диапазона случайным образом худший случай становится очень маловероятным и ожидаемое время выполнения алгоритма сортировки — O(n log n).
Выбирать опорным элементом средний из трех (первого, среднего и последнего элементов). Такой выбор также направлен против худшего случая.
Во избежание достижения опасной глубины рекурсии в худшем случае (или при приближении к нему) возможна модификация алгоритма, устраняющая одну ветвь рекурсии: вместо того, чтобы после разделения массива вызывать рекурсивно процедуру разделения для обоих найденных подмассивов, рекурсивный вызов делается только для меньшего подмассива, а больший обрабатывается в цикле в пределах этого же вызова процедуры. С точки зрения эффективности в среднем случае разницы практически нет: накладные расходы на дополнительный рекурсивный вызов и на организацию сравнения длин подмассивов и цикла — примерно одного порядка. Зато глубина рекурсии ни при каких обстоятельствах не превысит log2n, а в худшем случае вырожденного разделения она вообще будет не более 2 — вся обработка пройдёт в цикле первого уровня рекурсии.
Разбивать массив не на две, а на три части
_______________________________________________________________________________
Какова сложность пирамидальной сортировки?
O(n log n)
_______________________________________________________________________________
Какова сложность сортировки слиянием?
O(n log n)
_______________________________________________________________________________
Какова сложность поразрядной сортировки?
O(n·k)
_______________________________________________________________________________
Что такое задача выбора (k-я порядковая статистика)? Какова ее сложность?
k-ой порядковой статистикой набора элементов линейно упорядоченного множества называется такой его элемент, который является k-ым элементом набора в порядке сортировки.
При реализации вместо рекурсивных вызовов изменяются границы поиска статистики во внешнем цикле. В коде счититаем, что процедура partition принимает массив и границы отрезка, который будет рассечён возвращает индекс опорного элемента.
int findOrderStatistic(int[] array, int k) { int left = 0, right = array.length; while (true) { int mid = partition(array, left, right); if (mid == k) array[mid]; else if (k < mid) right = mid; else { k -= mid + 1; left = mid + 1; } } }
Однако, если считать, что partition возвращает все элементы рассматриваемого отрезка с равной вероятностью, то можно оценить матожидание времени работы как O(n).
Какова сложность алгоритма бинарного поиска?
При простом переборе делителей O(n sqrt(n) ) задача сортировки - упорядочивание элементов массива по неубыванию
_______________________________________________________________________________
Можно ли применить алгоритм бинарного поиска к списку?
Нельяз, т.к. в списке каждый элемент ссылки только на последующий элемент или на соседние элементы.
_______________________________________________________________________________
Структуры данных¶
Что такое структура?
Структура — конструкция программирования, позволяющая содержать в себе набор переменных различных типов, совокупность нескольких переменных, часто различных типов, сгруппированных под единым именем для удобства обращения.
_______________________________________________________________________________
Как выделить массив структур?
struct one_struct { int a; string b; }; one_struct* array_of_structs = new one_struct[n];
Что такое список?
Cпи́сок — структура данных, состоящая из узлов, каждый из которых содержит как собственно данные, так и одну или две ссылки («связки») на следующий и/или предыдущий узел списка.
_______________________________________________________________________________
Как устроен односвязный список?
Он состоит из узлов, которые содержат данные и ссылку на следующий узел списка (или предыдущий).
_______________________________________________________________________________
Что такое стек? Как он устроен, какие операции в нем есть?
Стек — структура данных, в которой доступ к элементам организован по принципу «последним пришёл — первым вышел». Чаще всего принцип работы стека сравнивают со стопкой тарелок: чтобы взять вторую сверху, нужно снять верхнюю.
Добавление элемента возможно только в вершину стека. Удаление элемента тоже возможно только из вершины стека, при этом второй сверху элемент становится верхним.
_______________________________________________________________________________