Лекция 3: Бинарный поиск. Связные списки

22
Лекция 3: Бинарный поиск. Связные списки. Курносов Михаил Георгиевич к.т .н. доцент Кафедры вычислительных систем Сибирский государственный университет телекоммуникаций и информатики http://www.mkurnosov.net

Upload: mikhail-kurnosov

Post on 05-Jul-2015

709 views

Category:

Education


2 download

TRANSCRIPT

Page 1: Лекция 3: Бинарный поиск. Связные списки

Лекция 3:

Бинарный поиск.

Связные списки.

Курносов Михаил Георгиевич

к.т.н. доцент Кафедры вычислительных систем

Сибирский государственный университет

телекоммуникаций и информатики

http://www.mkurnosov.net

Page 2: Лекция 3: Бинарный поиск. Связные списки

Контроль

2

1. Что такое вычислительная сложность алгоритма?

2. O(3n3 + 1000n2) = …. ?

3. O(n2 + logn) = ….

4. O(nlogn + n2 ) = …. ?

5. O(2n + n6 – 1000n3) = …. ?

6. O(n6 + n!) = …. ?

7. Асимптотическая сложность пузырьковой сортировки в

среднем случае (average case).

8. Асимптотическая сложность пузырьковой сортировки в

худшем случае (worst case).

9. Вычислительная сложность алгоритмы быстрой

сортировки (QuickSort).

Page 3: Лекция 3: Бинарный поиск. Связные списки

Поиск элемента в массиве (Search)

3

function Search(v[1:n], value)

for i = 1 to n do

if v[i] = value then

return i

end if

end for

return -1

end function

Вычислительная сложность линейного алгоритма поиска

элемента – O(n).

Можно ли ускорить алгоритм?

Page 4: Лекция 3: Бинарный поиск. Связные списки

Бинарный поиск (Binary Search)

4

function BinarySearch(v[1:n], key)

l = 1

h = n

while l <= h do

mid = (l + h) / 2

if v[mid] = key then

return mid

else if key > v[mid] then

l = mid + 1

else

h = mid - 1

end if

end while

return -1

end function

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

2 3 3 5 7 9 13 23 25 29 31 33 37 41 42 46 49 50 52 67 73 81 94

key = 100

Page 5: Лекция 3: Бинарный поиск. Связные списки

Бинарный поиск (Binary Search)

5

function BinarySearch(v[1:n], key)

l = 1

h = n

while l <= h do

mid = (l + h) / 2

if v[mid] = key then

return mid

else if key > v[mid] then

l = mid + 1

else

h = mid - 1

end if

end while

return -1

end function

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

2 3 3 5 7 9 13 23 25 29 31 33 37 41 42 46 49 50 52 67 73 81 94

key = 100

��, �

��, …,

��

� � = 1 – 1 итерация

� � = 23 – 5 итераций

� � = 32 – 6 итераций

��= 1, � = 2� ,

log�� = log� 2� = �

� � = � ���� � + �

� � = �(���� �)

Page 6: Лекция 3: Бинарный поиск. Связные списки

Связные списки (Linked Lists)

6

Связный список (Linked list) – динамическая структура

данных для хранения информации

Операция Описание Вычислительная

сложность

Сложность

по памяти

AddFront(a, x) Добавляет элемент x

в начало списка a

O(1) O(1)

AddEnd(a, x) Добавляет элемент x

в конец списка a

O(n) O(1)

Get(a, i) Возвращает i-й

элемент списка a

O(n) O(1)

Set(a, i, x) Присваивает i-у элементу

списка a значение x

O(n) O(1)

Size(a) Возвращает количество

элементов в списке a

O(1) или O(n) O(1)

Page 7: Лекция 3: Бинарный поиск. Связные списки

Односвязный список (Singly Linked List)

7

Данные Next Данные Next Данные Next Данные Next NULL

Head

� Размер списка заранее не известен – элементы добавляются

во время работы программы (динамически)

� Память под элементы выделяется динамически

(функции: malloc, calloc, free).

Page 8: Лекция 3: Бинарный поиск. Связные списки

Односвязный список (Singly linked list)

8

#include <stdio.h>

#include <stdlib.h>

struct listnode {

char *data; /* Data */

int value; /* Data */

struct listnode *next; /* Next node */

};

Page 9: Лекция 3: Бинарный поиск. Связные списки

Создание элемента (выделение памяти)

9

struct listnode *list_createnode(char *data,

int value)

{

struct listnode *p;

p = malloc(sizeof(*p));

if (p != NULL) {

p->data = data;

p->value = value;

p->next = NULL;

}

return p;

}Вычислительная сложность создания элемента

TCreateNode = O(1)

Page 10: Лекция 3: Бинарный поиск. Связные списки

Создание элемента (выделение памяти)

10

int main()

{

struct listnode *node;

node = list_createnode(“Ivanov Ivan”, 178);

return 0;

}

data: “Ivanov Ivan”

value: 178

next: NULL

Page 11: Лекция 3: Бинарный поиск. Связные списки

Добавление элемента в начало списка

11

NULL

head

Data

ValueNext

Data

ValueNext

NULL

head

Data

ValueNext

Data

ValueNext

Data

ValueNext

NULL

1. Создаем новый узел newnode в памяти

newnode

Page 12: Лекция 3: Бинарный поиск. Связные списки

Добавление элемента в начало списка

12

NULL

head

Data

ValueNext

Data

ValueNext

NULL

head

Data

ValueNext

Data

ValueNext

Data

ValueNext

2. Устанавливаем указатель next узла newnode на head

newnode

Page 13: Лекция 3: Бинарный поиск. Связные списки

Добавление элемента в начало списка

13

NULL

head

Data

ValueNext

Data

ValueNext

NULL

head

Data

ValueNext

Data

ValueNext

Data

ValueNext

3. Делаем головой списка узел newnode

newnode

Page 14: Лекция 3: Бинарный поиск. Связные списки

Добавление элемента в начало списка

struct listnode *list_addfront(

struct listnode *list,

char *data, int value)

{

struct listnode *newnode;

newnode = list_createnode(data, value);

if (newnode != NULL) {

newnode->next = list;

return newnode;

}

return list;

}

14TAddFront = O(1)

Page 15: Лекция 3: Бинарный поиск. Связные списки

Добавление элемента в начало списка

15

int main()

{

struct listnode *head;

head = list_addfront(NULL, "Ivanov Ivan",

178);

head = list_addfront(head, "Petrov Petr",

182);

return 0;

}

data: “Ivanov Ivan”

value: 178

next: NULL

data: “Petrov Petr”

value: 182

next: 0xdeadbeaf

Page 16: Лекция 3: Бинарный поиск. Связные списки

Поиск элемента в списке (Lookup)

16

head

� Начиная с головы списка просматриваем все узлы

и сравниваем ключи

data: “Ivanov Ivan”

value: 178

next: 0x3434ff99

data: “Petrov Petr”

value: 182

next: 0xdeadbeaf

data: “Sidorov Lev”

value: 169

next: NULL

Page 17: Лекция 3: Бинарный поиск. Связные списки

Поиск элемента в списке (Lookup)

17

struct listnode *list_lookup(

struct listnode *list,

char *data, int value)

{

for ( ; list != NULL; list = list->next) {

if (strcmp(list->data, data) == 0 &&

list->value == value)

{

return list;

}

}

return NULL;

} TLookup = Θ(n)

Page 18: Лекция 3: Бинарный поиск. Связные списки

Поиск элемента в списке (Lookup)

18

int main()

{

struct listnode *node, *p;

node = list_addfront(NULL, "Ivanov Ivan", 178);

node = list_addfront(node, "Petrov Petr", 182);

node = list_addfront(node, “Sidorov Lev", 169);

p = list_lookup(node, "Ivanov Ivan", 178);

if (p != NULL) {

printf("Data: %s\n", p->data);

}

return 0;

}

Page 19: Лекция 3: Бинарный поиск. Связные списки

Удаление элемента (Delete)

19

head

1. Находим элемент в списке

2. Корректируем указатели

3. Удаляем элемент из памяти

data: “Ivanov Ivan”

value: 178

next: 0x3434ff99

data: “Petrov Petr”

value: 182

next: 0xdeadbeaf

data: “Sidorov Lev”

value: 169

next: NULL

Три возможных ситуации:

a) удаляемый узел – в начале списка

b) удаляемый узел – внутри списка

c) удаляемый узел – в конце списка

Page 20: Лекция 3: Бинарный поиск. Связные списки

Удаление элемента (Delete)

struct listnode *list_delete(struct listnode *list,

char *data, int value)

{

struct listnode *p, *prev = NULL;

for (p = list; p != NULL; p = p->next) {

if (strcmp(p->data, data) == 0

&& p->value == value)

{

if (prev == NULL)

list = p->next;

else

prev->next = p->next;

free(p);

return list;

}

prev = p;

}

return NULL;

}20TDelete = Θ(n)

Page 21: Лекция 3: Бинарный поиск. Связные списки

Удаление элемента

21

int main()

{

struct listnode *node, *p;

node = list_addfront(NULL, "Ivanov Ivan", 178);

node = list_addfront(node, "Petrov Petr", 182);

node = list_addfront(node, “Sidorov Lev", 169);

p = list_delete(node, "Ivanov Ivan", 178);

if (p != NULL) {

printf("Deleted\n");

}

return 0;

}

Page 22: Лекция 3: Бинарный поиск. Связные списки

Задание

22

� Познакомиться с алгоритмом поразрядной сортировки

(Radix Sort, Sedgewick2001, С.401-419).

� Прочитать о реализации связных списков в “практике

программирования” (Kernighan2011, С.61-66).