1 of 288

So why do you need to know Algorithms and Data Structures in Front-end, anyway

2 of 288

Adam Leos

3 of 288

Adam Leos

  • Старший разработчик PlutoTV

4 of 288

5 of 288

Adam Leos

  • Старший разработчик PlutoTV

  • Автор веб-дополнения UnlimitedControl

6 of 288

7 of 288

8 of 288

Статья на Хабре:

  • Русский
  • English

9 of 288

Adam Leos

  • Старший разработчик PlutoTV

  • Автор веб-дополнения UnlimitedControl

  • Докладчик-идеолог

10 of 288

Что вы видите, это не то, что исполняется ©

11 of 288

Что вы видите, это не то, что исполняется ©

Нет плохого кода, а есть плохие компиляторы ©

12 of 288

Сложность алгоритма

13 of 288

Сложность алгоритма

Big O notation, O

14 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

15 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

16 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations

17 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

18 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n)

19 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n)

20 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

21 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic

22 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

23 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

24 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

c and n0 are constants, f(n) and g(n) are functions over non-negative integers

25 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

c and n0 are constants, f(n) and g(n) are functions over non-negative integers

26 of 288

Сложность алгоритма

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

c and n0 are constants, f(n) and g(n) are functions over non-negative integers

27 of 288

Algorithm Complexity

Big O notation, O

Omega notation, Ω

Theta Notation, θ

asymptotic notations, asymptotic complexity

O(n) Ο(log n) O(n * logn)

logarithmic polynomial

Ο(f(n)) = { g(n) : there exists c > 0 and n0 such that f(n) ≤ c.g(n) for all n > n0. }

c and n0 are constants, f(n) and g(n) are functions over non-negative integers

28 of 288

Сложность алгоритма

29 of 288

Сложность алгоритма

Как будет расти расход ресурсов* с увеличением размера входных данных.

30 of 288

Сложность алгоритма

Как будет расти расход ресурсов* с увеличением размера входных данных.

* время и память

31 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

32 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

33 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

34 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

35 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

36 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

37 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}��sumNumbersInArray([1, 2, 3, 4, 5]);

38 of 288

Сложность алгоритма

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}��sumNumbersInArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

39 of 288

Сложность алгоритма

Как будет расти расход ресурсов* с увеличением размера входных данных.

* время и память

40 of 288

Big O notation, O

41 of 288

Big O notation, O

42 of 288

Big O notation, O

Функция, которая описывает рост сложности алгоритма.

43 of 288

Big O notation, O

function sumNumbersInArray(array) {� let sum = 0;�� array.forEach(number => sum += number);�� return sum;�}�

44 of 288

Размер входных данных, ед.

45 of 288

Размер входных данных, ед.

1

46 of 288

Размер входных данных, ед.

1

100

47 of 288

Размер входных данных, ед.

1

100

1000

48 of 288

Размер входных данных, ед.

1

100

1000

10000

49 of 288

Размер входных данных, ед.

1

100

1000

10000

50 of 288

Размер входных данных, ед.

1

100

1000

10000

Количество операций

51 of 288

Размер входных данных, ед.

1

100

1000

10000

Количество операций

1

100

1000

10000

52 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

Количество операций

53 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(n)

Количество операций

54 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(n) - линейная

Количество операций

55 of 288

Big O

function simpleCalculate() {� const a = 1 + 2;� const b = 3 + 4;�� console.log('calculating...');�� return b - a;�}��simpleCalculate();�

56 of 288

Big O

function simpleCalculate() {� const a = 1 + 2;� const b = 3 + 4;�� console.log('calculating...');�� return b - a;�}��simpleCalculate();�

O(1)

57 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(1)

Количество операций

58 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(1) - константная (постоянная)

Количество операций

59 of 288

Big O

function simpleCalculate(number) {� const a = 1 + 2;� const b = 3 + 4;�� console.log('calculating...');�� return b - a + number;�}��simpleCalculate(8);

60 of 288

Big O

function simpleCalculate(number) {� const a = 1 + 2;� const b = 3 + 4;�� console.log('calculating...');�� return b - a + number;�}��simpleCalculate(8);

O(1)

61 of 288

Big O

function simpleCalculate(array) {� const a = 1 + 2;� const b = 3 + 4;� let additionalNumber = 0;�� array.forEach(num => additionalNumber += num);�� return b - a + additionalNumber;�}��simpleCalculate([1, 2, 5, 10, 1223]);

62 of 288

Big O

function simpleCalculate(array) {� const a = 1 + 2;� const b = 3 + 4;� let additionalNumber = 0;�� array.forEach(num => additionalNumber += num);�� return b - a + additionalNumber;�}��simpleCalculate([1, 2, 5, 10, 1223]);

O(n)

63 of 288

Big O

function simpleCalculate(array) {� const a = 1 + 2;� const b = 3 + 4;� const additionalNumber = array.length;�� return b - a + additionalNumber;�}��simpleCalculate([1, 2, 5, 10, 1223]);

64 of 288

Big O

function simpleCalculate(array) {� const a = 1 + 2;� const b = 3 + 4;� const additionalNumber = array.length;�� return b - a + additionalNumber;�}��simpleCalculate([1, 2, 5, 10, 1223]);

O(1)

65 of 288

Big O

function notSoSimpleCalculate(array) {� for (let i = 0; i < array.length; i++) {� for (let j = 0; j < array.length; j++) {� array[i] = array[i] + array[j];� }� }�� return array;�}��notSoSimpleCalculate([1, 2, 3]);

66 of 288

Big O

function notSoSimpleCalculate(array) {� for (let i = 0; i < array.length; i++) {� for (let j = 0; j < array.length; j++) {� array[i] = array[i] + array[j];� }� }�� return array;�}��notSoSimpleCalculate([1, 2, 3]);

O(n^2)

67 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(n^2) - квадратичная

Количество операций

68 of 288

Big O

function notSoSimpleCalculate(array) {� array.forEach(num => console.log(num));�� for (let i = 0; i < array.length; i++) {� for (let j = 0; j < array.length; j++) {� array[i] = array[i] + array[j];� }� }�� return array;�}

69 of 288

Big O

function notSoSimpleCalculate(array) {� array.forEach(num => console.log(num));�� for (let i = 0; i < array.length; i++) {� for (let j = 0; j < array.length; j++) {� array[i] = array[i] + array[j];� }� }�� return array;�}

O(n^2)

70 of 288

Big O

function mightBeSimpleCalculate(array) {� let total = 0;�� array.forEach(num => {� const additional = array.indexOf(num) > 5 ? 5 : 1;

� total = total + num + additional;� });�� return array;�}

71 of 288

Big O

function mightBeSimpleCalculate(array) {� let total = 0;�� array.forEach(num => {� const additional = array.indexOf(num) > 5 ? 5 : 1;

� total = total + num + additional;� });�� return array;�}

O(n^2)

72 of 288

Big O

function mightBeSimpleCalculate(array) {� let total = 0;�� array.forEach(num => {� const additional = array.indexOf(num) > 5 ? 5 : 1;

� total = total + num + additional;� });�� return array;�}

O(n^2)

73 of 288

Big O

function mightBeSimpleCalculate(array) {� let total = 0;�� array.forEach((num, index) => {� const additional = index > 5 ? 5 : 1;�� total = total + num + additional;� });�� return array;�}

O(n)

74 of 288

Пример роста в цифрах

75 of 288

Пример роста в цифрах

Входные данные - 10000 элементов

76 of 288

Пример роста в цифрах

O(1) - 1

Входные данные - 10000 элементов

77 of 288

Пример роста в цифрах

O(1) - 1

O(n) - 10000

Входные данные - 10000 элементов

78 of 288

Пример роста в цифрах

O(1) - 1

O(n) - 10000

O(n^2) - 100000000 (сто миллионов)

Входные данные - 10000 элементов

79 of 288

Пример роста в цифрах

O(1) - 1

O(n) - 10000

O(n^2) - 100000000 (сто миллионов)

O(n^3) - 1000000000000 (один триллион)

Входные данные - 10000 элементов

80 of 288

Пример роста в цифрах

O(1) - 1

O(n) - 10000

O(n^2) - 100000000 (сто миллионов)

O(n^3) - 1000000000000 (один триллион)

O(n!) очень много 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000……

Входные данные - 10000 элементов

81 of 288

82 of 288

Структуры данных

83 of 288

Структуры данных

Определенный способ организации данных для максимально эффективного использования

84 of 288

Структуры данных

  • Доступ (получить данные)
  • Поиск (найти данные)
  • Вставка (добавить данные)
  • Удаление (удалить данные)

85 of 288

86 of 288

Структуры данных

  1. Массивы

87 of 288

Массивы

const arr = [1, 2, 3];

88 of 288

Массивы

const arr = [1, 2, 3];

arr[1]; // 2

89 of 288

Массивы

const arr = [1, 2, 3];

arr[1]; // 2

O(1)

90 of 288

Массивы

const arr = [1, 2, 3];

arr[1]; // 2

arr[2]; // 3

O(1)

O(1)

91 of 288

Массивы

const arr = [1, 2, 3];

arr[1]; // 2

arr[2]; // 3

arr[9]; // undefined

O(1)

O(1)

O(1)

92 of 288

Массивы

const arr = [1, 2, 3];

arr[1]; // 2

arr[2]; // 3

arr[9]; // undefined

arr[0] = 4; // [4, 2, 3]

O(1)

O(1)

O(1)

O(1)

93 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

94 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

O(1)*

95 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

O(1)*

96 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

O(1)

O(1)*

97 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

arr.shift(); // [2, 3]

O(1)

O(1)*

98 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

arr.shift(); // [2, 3]

O(1)

O(n)

O(1)*

99 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

arr.shift(); // [2, 3]

arr.unshift(4); // [4, 2, 3]

O(1)

O(n)

O(1)*

100 of 288

Массивы

const arr = [1, 2, 3];

arr.push(4); // [1, 2, 3, 4]

arr.pop(); // [1, 2, 3]

arr.shift(); // [2, 3]

arr.unshift(4); // [4, 2, 3]

O(1)

O(n)

O(n)

O(1)*

101 of 288

Массивы

O(n)

102 of 288

Массивы

.map()

.slice()

.every()

.filter()

.indexOf()

.reduce()

.reverse()

.find()

.includes()

.toString()

O(n)

103 of 288

Структуры данных

  • Массивы
  • Объекты

104 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

105 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

obj.id // 1

106 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

obj.id // 1

O(1)

107 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

obj.id // 1

obj['name'] // 1

O(1)

O(1)

108 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

obj.surname = 'Leos';

obj['name'] = [];

O(1)

O(1)

109 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

Object.keys(obj) // ['id', 'name']

Object.values(obj) // [1, 'Adam']

110 of 288

Объекты

const obj = {� id: 1,� name: 'Adam',�};

Object.keys(obj) // ['id', 'name']

Object.values(obj) // [1, 'Adam']

O(n)

O(n)

111 of 288

Объекты

Посчитать символы в строке

112 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

113 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

114 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

115 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

116 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

117 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

118 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

119 of 288

Объекты

function countSymbols(string) {� const dict = {};�� for (let i = 0; i < string.length; i++) {� const iterableSymbol = string[i];� � if (dict[iterableSymbol] === undefined) dict[iterableSymbol] = 0;�� dict[iterableSymbol]++;� }�� return dict;�}

Посчитать символы в строке

120 of 288

Объекты

countSymbols('adam') // Object { a: 2, d: 1, m: 1 }

countSymbols('mississippi') // Object { m: 1, i: 4, s: 4, p: 2 }

Посчитать символы в строке

121 of 288

Полезный мапинг в

реальном мире

122 of 288

123 of 288

const shows = [� {� id: 1,� name: 'Rick and Morty',� categories: [

'Comedy',

'Animated',

'Science',

],

data: 1001010101001011,� },� {/.../},

{/.../},

{/.../},

{/.../},�];

124 of 288

const bannedShows = [� {

id: 1,

categories: [

'Comedy',

'Animated',

'Science',

],

},� {/.../},

{/.../},

{/.../},�];

const shows = [� {� id: 1,� name: 'Rick and Morty',� categories: [

'Comedy',

'Animated',

'Science',

],

data: 1001010101001011,� },� {/.../},

{/.../},

{/.../},

{/.../},�];

125 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

126 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

127 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

128 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

129 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

130 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

131 of 288

function ineffectiveBanning(shows) {� shows.forEach(show => {� const { id: showID } = show;�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;�� if (showID === bannedShowID) {

show.isBanned = true;

};� });� });�};

132 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

133 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

134 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

135 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

136 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

137 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

138 of 288

function effectiveBanning(shows) {� const bannedShowsIDMap = {};�� bannedShows.forEach(bannedShow => {� const { id: bannedShowID } = bannedShow;� bannedShowsIDMap[bannedShowID] = true;� };�� shows.forEach(show => {� const { id: showID } = show;�� if (bannedShowsIDMap[showID]) show.isBanned = true;� });�};

x100

139 of 288

Память в реальном мире

140 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

141 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

142 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

143 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

144 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

145 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

146 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

147 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels� .filter(filterEmptyTimelines)� .map(addIdentificator)� .map(modifyImages)

.map(removeParams)� .map(setSession)�� // more code�}

148 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

149 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

150 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

151 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

152 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

153 of 288

function enchanceApiResponse(apiResponse) {� const channels = apiResponse.channels.reduce((acc, channel) => {� if (hasEmptyTimelines(channel.timelines)) {� return acc;� }�� const enchancedChannel =

setChannelURL(reduceImagesObject(addIDToChannel(channel)));�� acc.push(enchancedChannel);�� return acc;� }, []);�� // more code�}

10-30%

154 of 288

Структуры данных

  • Массивы
  • Объекты
  • Графы

155 of 288

Граф

156 of 288

Граф

Вершина (узел)

157 of 288

Граф

Вершина (узел)

Ребро

158 of 288

Граф

Вершина (узел)

Ребро

1

13

9

54

11

6

70

159 of 288

Граф

1

13

9

54

11

6

70

160 of 288

Граф

1

13

9

54

11

6

70

Value (data) = 6

161 of 288

Граф

1

13

9

54

11

6

70

Value (data) = 6

Connections = [13, 70]

162 of 288

node = {� value: 6,� connections: [13, 70],�}

163 of 288

node = {� value: 6,� connections: [13, 70],�}

class Node {��}

164 of 288

node = {� value: 6,� connections: [13, 70],�}

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�}

165 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

166 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

const six = new Node(6);

167 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

const six = new Node(6);

six.value; // 6

168 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

const six = new Node(6);

six.value; // 6

const thirteen = new Node(13);�const seventy = new Node(70);�

169 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

const six = new Node(6);

six.value; // 6

const thirteen = new Node(13);�const seventy = new Node(70);��six.addConnection(thirteen);�six.addConnection(seventy);

170 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

node = {� value: 6,� connections: [13, 70],�}

const six = new Node(6);

six.value; // 6

const thirteen = new Node(13);�const seventy = new Node(70);��six.addConnection(thirteen);�six.addConnection(seventy);

six.connections;

// [{ value: 13, connections: [] }, { value: 70, connections: [] }];

171 of 288

class Graph {� �}

172 of 288

class Graph {� constructor() {� this.nodes = [];� } �}

173 of 288

class Graph {� constructor() {� this.nodes = [];� }�� addNode(node) {� this.nodes.push(node);� } �}

174 of 288

class Graph {� constructor() {� this.nodes = [];� }�� addNode(node) {� this.nodes.push(node);� }� � addEdge(node1, node2) {� node1.addConnection(node2);� node2.addConnection(node1);� }; �}

175 of 288

Граф

1

13

9

54

11

6

70

176 of 288

class Graph {� constructor() {� this.nodes = {};� }�� addNode(node) {� this.nodes.push(node);� }� � addEdge(node1, node2) {� node1.addConnection(node2);� node2.addConnection(node1);� }; �}

const ourGraph = new Graph();��const one = new Node(1);�const six = new Node(6);�const nine = new Node(9);�const eleven = new Node(11);�const thirteen = new Node(13);�const fiftyFour = new Node(54);�const seventy = new Node(70);

177 of 288

class Graph {� constructor() {� this.nodes = {};� }�� addNode(node) {� this.nodes.push(node);� }� � addEdge(node1, node2) {� node1.addConnection(node2);� node2.addConnection(node1);� }; �}

ourGraph.addNode(one);�ourGraph.addNode(six);�ourGraph.addNode(nine);�ourGraph.addNode(eleven);�ourGraph.addNode(thirteen);�ourGraph.addNode(fiftyFour);�ourGraph.addNode(seventy);��ourGraph.addEdge(one, thirteen);�ourGraph.addEdge(nine, thirteen);�ourGraph.addEdge(nine, fiftyFour);�ourGraph.addEdge(thirteen, eleven);�ourGraph.addEdge(thirteen, six);�ourGraph.addEdge(six, seventy);

178 of 288

Граф Гугл-карт

Kharkiv - [Lviv];

Lviv - [Kharkiv, Odessa];

Odessa - [Lviv];

179 of 288

Граф Гугл-карт

Kharkiv - [Lviv];

Lviv - [Kharkiv, Odessa];

Odessa - [Lviv];

Seattle

San Francisco

Las Vegas

Salt Lake City

San Francisco

180 of 288

Граф Гугл-карт

Kharkiv - [Lviv];

Lviv - [Kharkiv, Odessa];

Odessa - [Lviv];

181 of 288

const googleRoute = new Graph();��

182 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');�

183 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');�

const seattleData = {� name: 'Seattle',� coordinates: [� 47.7471188,� -125.6412592,� ],� state: 'WA',� country: 'USA',� weather: 'Sunny',� /.../�};

184 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');��googleRoute.addNode(seattle);�googleRoute.addNode(sanFrancisco);�googleRoute.addNode(lasVegas);�googleRoute.addNode(saltLakeCity);�

185 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');��googleRoute.addNode(seattle);�googleRoute.addNode(sanFrancisco);�googleRoute.addNode(lasVegas);�googleRoute.addNode(saltLakeCity);��googleRoute.addEdge(seattle, sanFrancisco);�googleRoute.addEdge(sanFrancisco, lasVegas);�googleRoute.addEdge(lasVegas, saltLakeCity);�googleRoute.addEdge(saltLakeCity, sanFrancisco);

186 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');��googleRoute.addNode(seattle);�googleRoute.addNode(sanFrancisco);�googleRoute.addNode(lasVegas);�googleRoute.addNode(saltLakeCity);��googleRoute.addEdge(seattle, sanFrancisco);�googleRoute.addEdge(sanFrancisco, lasVegas);�googleRoute.addEdge(lasVegas, saltLakeCity);�googleRoute.addEdge(saltLakeCity, sanFrancisco);

sanFrancisco.connections = [

seattle,

lasVegas,

saltLakeCity,

];

187 of 288

const googleRoute = new Graph();��const seattle = new Node('Seattle');�const sanFrancisco = new Node('San Francisco');�const lasVegas = new Node('Las Vegas');�const saltLakeCity = new Node('Salt Lake City');��googleRoute.addNode(seattle);�googleRoute.addNode(sanFrancisco);�googleRoute.addNode(lasVegas);�googleRoute.addNode(saltLakeCity);��googleRoute.addEdge(seattle, sanFrancisco);�googleRoute.addEdge(sanFrancisco, lasVegas);�googleRoute.addEdge(lasVegas, saltLakeCity);�googleRoute.addEdge(saltLakeCity, sanFrancisco);

sanFrancisco.connections = [

seattle,

lasVegas,

saltLakeCity,

];

seattle.connections = [

sanFrancisco

];

188 of 288

Логистика

189 of 288

Граф

1

13

9

54

11

6

70

190 of 288

Граф - ориентированный

1

13

9

54

11

6

70

191 of 288

Граф - взешенный

1

13

9

54

11

6

70

4

2

7

20

8

1

192 of 288

193 of 288

194 of 288

Где еще используются графы

  • Сеть (маршрутизация данных).
  • Логистика (маршруты, направления).
  • Телекоммуникации (планирование частот вышек).
  • Социальные сети (возможные знакомые).
  • Рекомендации.
  • Схемы.
  • И еще очень много где.

195 of 288

Структуры данных

  • Массивы
  • Объекты
  • Графы
  • Деревья

196 of 288

Деревья

1

13

9

54

11

6

70

197 of 288

Деревья

=

Связный ацикличный граф

1

13

9

54

11

6

70

198 of 288

Деревья

=

Связный ацикличный граф

1

13

9

54

11

6

70

199 of 288

Деревья

=

Связный ацикличный граф

1

13

9

54

11

6

70

200 of 288

DOM  дерево

201 of 288

202 of 288

203 of 288

const settings = {� �};

204 of 288

const settings = {� options: [� � ],�};�

205 of 288

const settings = {� options: [� {� � },� {� },� {� � },� // ... � ],�};�

206 of 288

const settings = {� options: [� {� name: 'video',� options: [...],� },� {� name: 'sound',� options: [...],� },� {� name: 'security',� options: [...],� },� // ... � ],�};�

207 of 288

const settings = {� options: [� {� name: 'video',� options: [...],� },� {� name: 'sound',� options: [...],� },� {� name: 'security',� options: [...],� },� // ... � ],�};�

[

{

name: 'subtitles',

options: [...],

},

{

name: 'brightness',

options: [...],

},

// ...�];�

208 of 288

Алгоритмы

209 of 288

Алгоритмы

  1. Поиск

210 of 288

function find(number, array) {� array.forEach((iterableNumber, index) => {� if (iterableNumber === number) {

console.log(`Found at index ${index}`);

}� });�}

211 of 288

function find(number, array) {� array.forEach((iterableNumber, index) => {� if (iterableNumber === number) {

console.log(`Found at index ${index}`);

}� });�}

O(n)

212 of 288

Поиск. Бинарный vs Последовательный

213 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

214 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

215 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

216 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

217 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2); const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

218 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

219 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

220 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

221 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

222 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

223 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

224 of 288

function binarySearch(number, array) {� let startIndex = 0;� let endIndex = array.length - 1;�� while (startIndex <= endIndex) {� const middleIndex = Math.floor((startIndex + endIndex) / 2);const middleValue = array[middleIndex];�� if (middleValue === number) {� console.log(`Found at index ${middleIndex}`);� } else if (middleValue < number) {� startIndex = middleIndex + 1;� } else {� endIndex = middleIndex - 1;� }� }�}

O(logn)

225 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(logn) - логарифмическая

Количество операций

226 of 288

Размер входных данных, ед.

1

100

1000

10000

1

100

1000

10000

O(logn) - логарифмическая

2el => 1

4el => 2

8el => 3

1000el => ~10

10000el => ~13

100000el => ~16

Количество операций

227 of 288

Бинарное

Дерево

1

13

9

54

11

6

70

228 of 288

Бинарное

Дерево

1

3

9

54

11

6

70

229 of 288

Бинарное

Дерево

1

3

5

54

11

6

70

230 of 288

Бинарное

Дерево

1

3

5

54

71

6

70

231 of 288

Поиск. Бинарное дерево

232 of 288

class Node {� constructor(value) {� this.value = value;� this.connections = [];� }�� addConnection(node) {� this.connections.push(node);� }�}

233 of 288

class Node {� constructor(value) {� this.value = value;� this.left = null;� this.right = null;� }�}

234 of 288

class Tree {� constructor() {� this.root = null;� } �}

235 of 288

class Tree {� constructor() {� this.root = null� }

insert(data) {� const newNode = new Node(data);� � if (this.root === null) {

this.root = newNode;

} else {

this.insertNode(this.root, newNode);

}� } �}

236 of 288

Бинарное дерево

237 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

238 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

239 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

240 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

241 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

242 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

243 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

244 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;else {

this.insertNode(parentNode.right, newNode);

}

}�}�

245 of 288

insertNode(parentNode = this.head, newNode) {� if (newNode.data < parentNode.data) {� if (parentNode.left === null) parentNode.left = newNode;� else {

this.insertNode(parentNode.left, newNode);

}� } else {� if (parentNode.right === null) parentNode.right = newNode;� else {

this.insertNode(parentNode.right, newNode);

}

}�}�

246 of 288

247 of 288

Алгоритмы

  • Поиск
  • Сортировки

248 of 288

Сортировка Пузырьком (bubble sort)

249 of 288

Сортировка Пузырьком (bubble sort)

O(n^2)

250 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

251 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

252 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

253 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

254 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

255 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

256 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

257 of 288

function bubble(arr) {� const length = arr.length;�� for (let i = 0; i < length; i++) {� for (let j = 0; j < length - i - 1; j++) {� const current = arr[j];� const next = arr[j + 1];�� if (current > next) {� arr[j] = next;� arr[j + 1] = current;� }� }� }�� return arr;�}

258 of 288

Сортировка слиянием

(Merge sort)

259 of 288

Сортировка слиянием

(Merge sort)

O(n * logn)

260 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

261 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

262 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

263 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

264 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

265 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

266 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

267 of 288

function mergeSort(unsortedArray) {� if (unsortedArray.length <= 1) {� return unsortedArray;� }�� const middle = Math.floor(unsortedArray.length / 2);� const left = unsortedArray.slice(0, middle);� const right = unsortedArray.slice(middle);�� return merge(� mergeSort(left), mergeSort(right)� );�}

268 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

269 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

270 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

271 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

272 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

273 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

274 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

275 of 288

function merge(left, right) {� const resultArray = [];� let leftIndex = 0;� let rightIndex = 0;�� while (leftIndex < left.length && rightIndex < right.length) {� if (left[leftIndex] < right[rightIndex]) {� resultArray.push(left[leftIndex]);� leftIndex++;� } else {� resultArray.push(right[rightIndex]);� rightIndex++;� }� }�� return resultArray� .concat(left.slice(leftIndex))� .concat(right.slice(rightIndex));�}

276 of 288

Память vs. Время

277 of 288

Bogosort

(самая неэффективная сортировка)

278 of 288

Bogosort

(самая неэффективная сортировка)

O(n * n!)

279 of 288

Уже хорошо работает

Array.sort()

280 of 288

Уже хорошо работает

Array.sort()

Разные имплементации в разных браузерах. (и в разных версиях).

281 of 288

Уже хорошо работает

Array.sort()

Разные имплементации в разных браузерах. (и в разных версиях).

В целом, базируется на сортировках слиянием и быстрой сортировке (в зависимости от типа данных в массиве).

282 of 288

Уже хорошо работает

Array.sort()

Разные имплементации в разных браузерах. (и в разных версиях).

В целом, базируется на сортировках слиянием и быстрой сортировке (в зависимости от типа данных в массиве).

+ на небольших массивах (до 10 элементов) используется сортировка вставками.

283 of 288

Заключение

284 of 288

Заключение

  • Вам не нужно знать все алгоритмы и структуры данных. Самые необходимые знания, дающие больше всего пользы, в то же время являются и самыми простыми в освоении.

285 of 288

Заключение

  • Вам не нужно знать все алгоритмы и структуры данных. Самые необходимые знания, дающие больше всего пользы, в то же время являются и самыми простыми в освоении.
  • Нет необходимости помнить все реализации, вы даже можете забыть какие-то самые важные. Достаточно один раз разобраться в них, чтобы иметь представление о возможностях.

286 of 288

Заключение

  • Вам не нужно знать все алгоритмы и структуры данных. Самые необходимые знания, дающие больше всего пользы, в то же время являются и самыми простыми в освоении.
  • Нет необходимости помнить все реализации, вы даже можете забыть какие-то самые важные. Достаточно один раз разобраться в них, чтобы иметь представление о возможностях.
  • Анализируйте ваши алгоритмы. Задумывайтесь над их эффективностью. Чем эффективнее код вы создаете, тем производительнее и надежнее будет ваш продукт (и тем круче вы станете как разработчик)

287 of 288

Материалы

Теория

Практика

288 of 288

Q&A

Слайды

Контакты