Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Списки на СИ++_ Указания к л.р..doc
Скачиваний:
5
Добавлен:
09.11.2019
Размер:
102.4 Кб
Скачать

2.3 Двусвязный список

Во многих задачах возникает необходимость организовать эффективное перемещение по списку как в прямом, так и в обратном направлениях или заданным признакам элемента найти предшествующий и последующий элементы списка. Для решения подобных задач можно каждому элементу списка приписать указатели на следующий и предыдущий элементы, т,е. организовать двусвязный список.. Таким образом, линейный двусвязный список отличается от односвязного тем, что каждое звено списка помимо содержательной информации включает два указателя. Один из которых (прямой указатель) адресует следующий элемент списка, а другой – обратный указатель – предыдущий элемент списка, как показано на рисунке 3.

beg

данные

Null

Начало списка

rex

. . .

. . .

L2

данные

L1

L2

данные

L1

L2

end

данные

L1

Null

(Последний элемент списка)

Элементы такого структурного типа описываются следующим образом:

struct имя_структурного_типа

{

элементы _структуры; /* данные */

struct имя_структурного_типа * указатель;

struct имя_структурного_типа * указатель;

};

Продемонстрируем некоторые особенности обработки двусвязных списков на примере рассмотренной выше задачи. Для работы с двусвязными списками будем, как и ранее, использовать три указателя : beg – на начало списка, end – на последний элемент, уже включенный в список и rex – указатель для “перебора” элементов списка. Приведенная ниже программа формирует двусвязный список для поставленной задачи.

#include <iostream>

#include <conio.h>

using namespace std;

//описание структуры "Звено списка"

struct cell2

{ char sign[10];

int weight;

cell2 *pc1;

cell2 *pc2;

};

void main()

{ cell2 *rex; //указатель для перебора звеньев списка

cell2 *beg = NULL; //начало списка

cell2 *end = NULL; //конец списка

cout << "Input value struct\n"; //введите значения списка

//цикл ввода и формирования списка

do

{ //выделить память для очередного звена списка

cell2 *rex = new cell2;

//ввести значения элементов звена

cout << "sign = ";

cin >> rex->sign;

cout << "weight = ";

cin >> rex->weight;

if(rex->weight == 0)

{ delete [] rex;

break; //выход из цикла ввода списка

}

//включить звено в список

if(beg == NULL && end == NULL)

{ beg = rex; //список пуст - включить введенный элемент в список первым

beg->pc1 = NULL;

}

else

{ end->pc2 = rex; //включить звено в уже существующий список

rex->pc1 = end;

}

end = rex;

end->pc2 = NULL;

}

while(1); //конец ввода списка

//напечатать список

cout << "\nContent of list"; //Содержимое списка

rex = beg;

while(rex != NULL)

{ cout << "\nsign = " << rex->sign

<< "\tweight = " << rex->weight;

rex = rex->pc2;

}

getch();

}

Обратите внимание на то, что вместо структур типа struct cell используется структурный тип struct cell2, имеющий дополнительное поле для второго указателя. Остальные особенности программы поясняются комментариями в тексте программы.