- •1.Связное представление данных в памяти
- •2.Односвязный список: структура, машинное представление , операции.
- •3. Двусвязный список: структура, машинное представление , операции.
- •Удаление элемента из двунаправленного списка
- •Поиск элемента в двунаправленном списке
- •Проверка пустоты двунаправленного списка
- •Удаление двунаправленного списка
- •4. Кольцевой список: структура, машинное представление , операции.
- •5.Очередь: понятие, структура, операции
- •10.Открытое хеширование
- •11.Закрытое хеширование
- •13.Понятие дерева, бинарного дерева, сбалансированного дерева.
- •14.Алгоритм горизонтального обхода дерева.
- •15.Алгоритм вертикального обхода дерева.
- •16.Обход графа в ширину.
- •17.Алгоритм обода графа в глубину
- •18.Алгоритм Флойда-Уоршалла
- •19.Алгоритм Дейкстры.
- •20. Алгоритм Белламана-Форда
- •21.Алгоритмы поиска и сортировки деревьями: метод ветвей и границ.
- •22.Алгоритмы поиска и сортировки деревьями: перебор с возвратом.
- •2.1.1. Общая схема
Удаление элемента из двунаправленного списка
Из динамических структур можно удалять элементы, так как для этого достаточно изменить значения адресных полей. Операция удаления элемента из двунаправленного списка осуществляется во многом аналогично удалению из однонаправленного списка (рис. 29.6).
Рис. 29.6. Удаление элемента из двунаправленного списка
/*удаление элемента с заданным номером из двунаправленного списка*/
Double_List* Delete_Item_Double_List(Double_List* Head,
int Number){
Double_List *ptr;//вспомогательный указатель
Double_List *Current = Head;
for (int i = 1; i < Number && Current != NULL; i++)
Current = Current->Next;
if (Current != NULL){//проверка на корректность
if (Current->Prior == NULL){//удаляем первый элемент
Head = Head->Next;
delete(Current);
Head->Prior = NULL;
Current = Head;
}
else {//удаляем непервый элемент
if (Current->Next == NULL) {
//удаляем последний элемент
Current->Prior->Next = NULL;
delete(Current);
Current = Head;
}
else {//удаляем непервый и непоследний элемент
ptr = Current->Next;
Current->Prior->Next =Current->Next;
Current->Next->Prior =Current->Prior;
delete(Current);
Current = ptr;
}
}
}
return Head;
}
Поиск элемента в двунаправленном списке
Операция поиска элемента в двунаправленном списке реализуется абсолютно аналогично соответствующей функции для однонаправленного списка. Поиск элемента в двунаправленном списке можно вести:
а) просматривая элементы от начала к концу списка;
б) просматривая элементы от конца списка к началу;
в) просматривая список в обоих направлениях одновременно: от начала к середине списка и от конца к середине (учитывая, что элементов в списке может быть четное или нечетное количество).
//поиск элемента в двунаправленном списке
bool Find_Item_Double_List(Double_List* Head,
int DataItem){
Double_List *ptr; //вспомогательный указатель
ptr = Head;
while (ptr != NULL){//пока не конец списка
if (DataItem == ptr->Data) return true;
else ptr = ptr->Next;
}
return false;
}
Проверка пустоты двунаправленного списка
Операция проверки двунаправленного списка на пустоту осуществляется аналогично проверки однонаправленного списка.
//проверка пустоты двунаправленого списка
bool Empty_Double_List(Double_List* Head){
if (Head!=NULL) return false;
else return true;
}
Удаление двунаправленного списка
Операция удаления двунаправленного списка реализуется аналогично удалению однонаправленного списка.
//освобождение памяти, выделенной под двунаправленный список
void Delete_Double_List(Double_List* Head){
if (Head != NULL){
Delete_Double_List(Head->Next);
delete Head;
}
}
4. Кольцевой список: структура, машинное представление , операции.
Под кольцевым (циклическим) списком понимается список, в котором указатель из некоторой ячейки направлен на такое место в списке, откуда данная ячейка может быть достигнута снова [1]. Очевидно, что теперь мы можем из любого звена списка, "перемещаясь" по указателям достичь любого другого звена.
Кольцевым списком (кольцом) на базе линейного однонаправленного списка называется линейный список, в котором указатель из некоторого звена направлен на такое звено в списке, из которого данное звено может быть достигнуто вновь.
Опишем два способа представления однонаправленного кольцевого списка с заглавным звеном:
Рис.1.
Кольцо с удаленным заглавным звеном
Такой кольцевой список будем называть кольцевым списком с удаленным заглавным звеном.
Пустой кольцевой список с удаленным заглавным звеном представим так:
Рис.2.
Пустое кольцо с удаленным заглавным
звеном
Рис.3.
Кольцо с включенным заглавным звеном
А этот кольцевой список назовем кольцевым списком с включенным заглавным звеном.
Пустой кольцевой список с включенным заглавным звеном представим так:
Рассмотрим способ построения кольцевого
списка. Построение выполняется так же,
как и в случае линейного однонаправленного
списка с заглавным звеном, только после
окончания ввода элементов кольцевого
списка, в поле указателя последнего
звена списка помещается адрес звена,
следующего за заглавным.
Сказанное легко формализуется:
void POSTROENIE (node **phead)
//*phead - указатель на заглавное звено.
{
int el;
struct node *t;
// Вначале сформируем заглавное звено.
*phead = new (node);
t = *phead; (*t).sled = NULL;
cout<<"Вводите элементы кольца: "; cin>>el;
while (el!=0)
{ (*t).sled = new (node); t = (*t).sled; (*t).elem = el;
cin>>el;
}
(*t).sled = (*(*phead)).sled;
}
Вывод на экран дисплея содержимого информационных полей кольцевого списка производится до тех пор, пока рабочий указатель, перемещающийся по кольцу, не совпадет с указателем на звено, расположенное после заглавного:
void VYVOD (node **phead)
{
struct node *t;
t = (**phead).sled; cout<< "Кольцо: ";
if (t!=NULL)
{ cout<<(*t).elem; t = (*t).sled;
while (t!=(**phead).sled)
{
cout<<(*t).elem;
t = (*t).sled; }
}
else cout<<"пусто!\n";
}
