Скачать презентацию Структуры данных План лекции ü Что такое Скачать презентацию Структуры данных План лекции ü Что такое

лекция-структуры_данных.ppt

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

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

План лекции: ü Что такое структуры данных и зачем они нужны ü Стек ü План лекции: ü Что такое структуры данных и зачем они нужны ü Стек ü Очередь ü Дек ü Множество и система множеств ü Список ü Очередь по приоритету ü Словарь

Что такое структуры данных и зачем они нужны z Решение любой задачи есть обработка Что такое структуры данных и зачем они нужны z Решение любой задачи есть обработка данных – выполнение над данными некоторых операций z Набор операций для каждой задачи свой, однако некоторые наборы операций часто используются при решении задач z Полезно придумать наиболее эффективный способ организации данных и операций над ними z После этого мы имеем в наличии «черный ящик» - нашу структуру данных и операций z Для конкретной задачи это позволяет отвлечься от деталей реализации структуры и сосредоточиться на особенностях задачи z Физически структура данных может быть реализована по-разному, но нужно стремиться к наиболее эффективной (по времени работы с ней и по количеству расходуемой памяти) реализации

Стек z Стек – это структура данных, из которой данные извлекаются в порядке, обратном Стек z Стек – это структура данных, из которой данные извлекаются в порядке, обратном их поступлению z Стек поддерживает операции: z Push(x) – добавляет объект x в стек z Pop – извлекает элемент из стека z Empty – возвращает ИСТИНА, если стек пуст, либо ЛОЖЬ. z Пример: x 1: =2 x 2: =4 x 3: =6 2 Push(x 1) Push(x 2) Push(x 3) 4 6 x 1=Pop() x 2=Pop() x 3=Pop() x 1=6 x 2=4 x 3=2

Реализация стека z Будем реализовывать стек в массиве объектов S[0. . N] z Заведем Реализация стека z Будем реализовывать стек в массиве объектов S[0. . N] z Заведем переменную – указатель вершины стека Top. z Данные будут храниться последовательно в ячейках от S[0] до S[Top] z Всего в стеке Top+1 элементов, если Top=-1 – стек пуст, самый поздний элемент находится в ячейке S[Top] void Push(int x){ Top++; S[Top]=x; return; } int Pop(){ Top--; return S[Top+1]; } z Пример: обход лабиринта с помощью стека bool Empty(){ if (Top==-1) return true; else return false; }

Стек в STL Объявление экземпляра стека: stack<type> variable; Операции: void push(value) – поместить value Стек в STL Объявление экземпляра стека: stack variable; Операции: void push(value) – поместить value в стек void pop() – удалить элемент из стека type top() – получить верхний элемент стека bool empty() – возвращает true, если стек пуст, иначе false Пример: #include using namespace std; stack S; int main() { S. push(8); S. push(7); int x = S. top(); //x==7 S. pop(); bool b = S. empty(); return 0; }

Очередь z Очередь – это структура данных, из которой данные извлекаются в порядке их Очередь z Очередь – это структура данных, из которой данные извлекаются в порядке их поступления z Очередь поддерживает операции: z Enqueue(x) – добавляет объект x в очередь z Dequeue – извлекает элемент из очереди z Empty – возвращает ИСТИНА, если очередь пуста, либо ЛОЖЬ. z Пример: x 1: =2 x 2: =4 x 3: =6 Enqueue(x 1) x 1=Dequeue() Enqueue(x 2) x 2=Dequeue() Enqueue(x 3) x 3=Dequeue() 2 4 6 x 1=2 x 2=4 x 3=6

Реализация очереди z Будем реализовывать очередь в массиве объектов S[0. . N] z Заведем Реализация очереди z Будем реализовывать очередь в массиве объектов S[0. . N] z Заведем две переменных – указатель головы очереди Head и указатель хвоста очереди Tail. z Данные будут храниться последовательно в ячейках от S[Tail] до S[Head] (при этом Tail может быть больше Head) z Всего в очереди Count элементов, Count=0 – очередь пуста. void Enqueue(int x){ Count++; Head=(Head+1)%N; S[Head]=x; return; } int Dequeue(){ Count--; int tmp=S[Tail]; Tail=(Tail+1)%N; return tmp; } bool Empty_(){ if (Count==0) return true; else return false; } z Пример: обход лабиринта с помощью очереди

Очередь в STL Объявление экземпляра очереди: queue<type> variable; Операции: void push(value) – поместить value Очередь в STL Объявление экземпляра очереди: queue variable; Операции: void push(value) – поместить value в очередь void pop() – удалить элемент из очереди type front() – получить первый по очереди элемент bool empty() – возвращает true, если очередь пуста, иначе false Пример: #include using namespace std; queue Q; int main() { Q. push(8); Q. push(7); int x = Q. front(); //x==8 Q. pop(); bool b = Q. empty(); return 0; }

Дек z Дек – это структура данных, в которой добавление и извлечение данных разрешено Дек z Дек – это структура данных, в которой добавление и извлечение данных разрешено с обоих концов z Дек поддерживает операции: z Push_front(x) – добавляет объект x в начало дека z Push_back(x) – добавляет объект x в конец дека z Pop_front – извлекает объект из начала дека z Pop_back – извлекает объект из конца дека z Empty – возвращает ИСТИНА, если дек пуст, либо ЛОЖЬ. z Пример: x 1: =2 x 2: =4 x 3: =6 Push_front(x 1) Push_front(x 2) Push_back(x 3) x 1=Pop_front() x 2=Pop_back() x 3=Pop_front() back x 1=4 x 2=6 x 3=2 front 6 2 4

Дек в STL Объявление переменной стека: deque<type> variable; Операции: void push_front(value) – поместить value Дек в STL Объявление переменной стека: deque variable; Операции: void push_front(value) – поместить value в начало дека void push_back(value) – поместить value в конец дека void pop_front() – удалить элемент из начала дека void pop_back() – удалить элемент из конца дека type front() – получить первый элемент type back() – получить последний элемент bool empty() – возвращает true, если очередь пуста, иначе false

Множество и система множеств z Множества – это неупорядоченные наборы элементов, набранные из данного Множество и система множеств z Множества – это неупорядоченные наборы элементов, набранные из данного универсального множества U (универсума). z Операции над множествами: z Member(x, S) – является ли объект x элементом множества S z Include(x, S) – добавить объект х в множество S z Exclude(x, S) – удалить объект х из множества S z Union(A, B) – построить объединение множеств A и B z Intersect(A, B) – построить пересечение множеств A и B z Пример: A={2, 3, 4} B={2, 4, 6} C=Union(A, B) D=Intersect(A, B) Include(5, A) C={2, 3, 4, 6} D={2, 4} A={2, 3, 4, 5}

Реализация множеств z Если универсум большой или неограниченный, лучшим решением будет представление множества словарем Реализация множеств z Если универсум большой или неограниченный, лучшим решением будет представление множества словарем z Для небольших универсумов удобно представлять множество битовым вектором (массивом) z Бит i выставлен в 1, если объект с номером i принадлежит S. void Include(int x){ S[x]=1 return; } void Exclude(int x){ S[x]=0; return; } void Union(A, B){ for(i=0; i

Список z Список – это структура данных, в которой данные записаны в определенном порядке. Список z Список – это структура данных, в которой данные записаны в определенном порядке. Порядок определяется указателями, связывающими элементы списка. z Список поддерживает операции: z Find(x) – возвращает указатель на объект x, либо нулевой указатель, если x отсутствует в списке z Insert(x) – добавляет элемент x в список z Delete(x) – удаляет элемент x из списка z Пример: x 1: =2 x 2: =4 x 3: =6 Insert(x 1) Insert(x 2) Insert(x 3) 2 x 1=Find(x 1) x 2=Find(x 2) x 3=Find(x 3) 4 x 1=0 x 01 x 2=0 x 02 x 3=0 x 03 6

Реализация списка z Будем реализовывать список в массиве объектов L[1. . N] z Заведем Реализация списка z Будем реализовывать список в массиве объектов L[1. . N] z Заведем две переменных – указатель головы списка Head и указатель хвоста списка Tail. z Каждый объект L[i] имеет указатели на следующий (Next) и предыдущий (Prev) элементы списка, а также поле данных Data z Значение указателя 0 – пустой указатель int Find(x){ i=Head; while(i!=0) { if(L[i]. Data==x. Data) return i; i=L[i]. Next; } //end while return 0; }; //не учитывает вставку в пустой список void Insert(x){ N++; L[N]=x; L[N]. Next=0; L[N]. Prev=Tail; L[Tail]. Next=N; Tail=N; return; }; //из середины списка void Delete(x){ i=Head; while(i!=0) { if(L[i]. Data==x. Data){ L[L[i]. Prev]. Next= L[i]. Next; L[L[i]. Next]. Prev= L[i]. Prev return; } //end if i=L[i]. Next; } //end while return; };

Список в STL Объявление экземпляра очереди: list<type> variable; Операции: void push_back(value) – поместить value Список в STL Объявление экземпляра очереди: list variable; Операции: void push_back(value) – поместить value в конец списка void push_front(value) – поместить value в начало списка void pop_back() – удалить элемент из конца списка void pop_front() – удалить элемент из начала списка type front() – получить первый элемент списка type back() – получить первый элемент списка bool empty() – возвращает true, если список пуст, иначе false void insert(iter, value)- поместить value перед элементом по итератору iter void erase(iter) – удалить элемент, расположенный по итератору iter begin() – получить итератор на первый элемент списка iter end() – получить итератор на элемент списка, следующий за последним

Список в STL – примеры //вставка в отсортированный список void ins_in_list(int k){ list<int>: : Список в STL – примеры //вставка в отсортированный список void ins_in_list(int k){ list: : iterator i; i=l. begin(); while (*i: : iterator i; i=l. begin(); while (*i!=k && i!=l. end()) i++; l. erase(i); return; }

Очередь по приоритету z Иногда необходимо работать с динамически изменяющимся множеством объектов, среди которых Очередь по приоритету z Иногда необходимо работать с динамически изменяющимся множеством объектов, среди которых часто нужно находить объект с минимальным ключом z Очередь по приоритету – это структура данных, в которой данные обрабатываются в порядке приоритета (значения ключа) z Поддерживает следующие операции: z Insert(x) – добавляет объект x в очередь z Maximum – получает объект с максимальным значением ключа z Extract_max – удаляет из очереди объект с максимальным значением ключа z Пример: x 1: =6 x 2: =2 x 3: =4 Insert(x 1) Insert(x 2) Insert(x 3) x 1=Maximum() Extract_max() x 2=Maximum() x 3=Maximum() x 1=6 x 2=4 x 3=4

Реализация очереди по приоритету z Будем использовать реализацию очереди, наз. бинарной кучей z Бинарная Реализация очереди по приоритету z Будем использовать реализацию очереди, наз. бинарной кучей z Бинарная куча – это массив H[1. . N] в котором для каждого H[i] (i=1. . N) выполняются условия: z 1) H[i] >= H[2 i] 2) H[i] >= H[2 i+1] z Данные будут храниться последовательно в ячейках от S[1] до S[N] void Insert(int x){ int i, tmp; N++; H[N]=x; i=N; while ((i>1) && (H[i]>H[i/2])) { swap(H[i], H[i/2]) i=i/2; } //end while return; }; void Extract_max(){ int max, i, tmp; H[1]=H[N]; N--; i=1; while (2*i<=N) { if ((2*i==N) || (H[2*i]>H[2*i+1])) max=2*i; else max=2*i+1; if (H[i]>=H[max]) break; swap(H[i], H[max]); i=max; } //end while return; };

Очередь по приоритету в STL Объявление экземпляра очереди по приоритету: priority_queue<type> variable; Операции: void Очередь по приоритету в STL Объявление экземпляра очереди по приоритету: priority_queue variable; Операции: void push(value) – поместить value в очередь void pop() – удалить максимальный элемент из очереди type top() – получить максимальный элемент bool empty() – возвращает true, если очередь пуста, иначе false Пример: #include using namespace std; priority_queue Q; int main() { Q. push(3); Q. push(8); Q. push(7); int x = Q. top(); //x==8 Q. pop(); bool b = Q. empty(); return 0; }

Словарь z Словарь – это структура данных, поддерживающая извлечение не по положению, а по Словарь z Словарь – это структура данных, поддерживающая извлечение не по положению, а по содержанию (значению ключа). z Поддерживает следующие операции: z Insert(x) – добавляет объект x в словарь z Delete(x) – удаляет объект x (имеющий ключ k) из словаря z Search(k) – ищет в словаре объект с ключом k z Различают следующие виды словарей: z Статические – строятся один раз и поддерживают только поиск z Полудинамические – поддерживают вставку, но не удаление z Динамические

Словарь в STL Объявление экземпляра словаря(отображения): map<key_type, data_type> variable; Операции: data_type operator[](key_type) – получить Словарь в STL Объявление экземпляра словаря(отображения): map variable; Операции: data_type operator[](key_type) – получить данные по ключу, добавить новую пару (ключ, данные) void erase(key) – удалить элемент с ключом key void erase(iter) – удалить элемент по итератору iter find(key) – найти элемент с ключом key iter begin() – получить итератор на элемент с минимальным ключом iter end() – получить итератор на элемент после элемента с максимальным ключом

Словарь в STL (пример) #include <map> using namespace std; map<int, double> M; map<int, double>: Словарь в STL (пример) #include using namespace std; map M; map: : iterator i; int main() { M[3] = 3. 14; M[15] = 6. 28; i = M. find(15); int k = (*i). first; // k == 15 double x = (*i). second; // x == 6. 28 i = M. find(14); // i == M. end() i = M. end(); i--; double x = (*i). second; // x == 6. 28 M. erase(15); return 0; }