Из динамических структур можно удалять элементы, так как для этого достаточно изменить значения адресных полей. Операция удаления элемента из двунаправленного списка осуществляется во многом аналогично удалению из однонаправленного списка ( рис. 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; } }
Пример 1. N -натуральных чисел являются элементами двунаправленного списка L, вычислить: X1*Xn+X2*Xn-1+...+Xn*X1. Вывести на экран каждое произведение и итоговую сумму.
Создание структуры, формирование списка и вывод на печать рассмотрены ранее. Приведем функции для реализации продвижения по списку в обоих направлениях и нахождения итоговой суммы.
//поиск последнего элемента списка Double_List* Find_End_Item_Double_List(Double_List* Head){ Double_List *ptr; //дополнительный указатель ptr = Head; while (ptr->Next != NULL){ ptr = ptr->Next; } return ptr; } //итоговая сумма произведений void Total_Sum(Double_List* Head) { Double_List* lel = Head; Double_List* mel = Find_End_Item_Double_List(Head); int mltp,sum=0; while(lel != NULL) { mltp = (lel->Data)*(mel->Data);//умножение элементов printf("\n\n%d * %d = %d",lel->Data,mel->Data,mltp); sum = sum + mltp;//суммирование произведений lel = lel->Next; //идем по списку из первого элемента в последний mel = mel->Prior; //идем по списку из последнего элемента в первый } printf("\n\n Итоговая сумма равна %d",sum); }
Двунаправленный (двусвязный) список – это структура данных, состоящая из последовательности элементов, каждый из которых содержит информационную часть и два указателя на соседние элементы.
Длина списка – это величина, равная числу элементов в списке.
Линейный список – это список, отражающий отношения соседства между элементами.
Однонаправленный (односвязный) список – это структура данных, представляющая собой последовательность элементов, в каждом из которых хранится значение и указатель на следующий элемент списка.
Пустой список – это список нулевой длины.
Связанный список – это структура, элементами которой служат записи одного формата, связанные друг с другом с помощью указателей, хранящихся в самих элементах.
Список – это упорядоченное множество, состоящее из переменного числа элементов, к которым применимы операции включения, исключения.
Указатель начала списка (голова списка) – это указатель на первый элемент списка.