Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЯП - ПОИТ (Бахтизин) часть 1 редакт.doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
1.76 Mб
Скачать

9.2.2. Двусвязные списки

Двусвязный список представляет собой последовательность связанных узлов, каждый из которых, в отличие от однонаправленного списка, содержит поле данных и два указателя, один из которых содержит адрес памяти, где хранится следующий элемент списка, а второй – адрес памяти, где хранится предыдущий элемент списка. Это дает возможность перемещаться по списку как с начала в хвост, так и с хвоста в начало.

На рис 9.3 изображен двусвязный список, каждый узел которого включает в себя поле данных типа char, указатель на следующий элемент – nextPtr и указатель на предыдущий элемент – predPtr. Указатель на начало списка – HeadPtr, на конец – LastPtr.

Рис. 9.3. Двусвязный список

9.2.3. Циклические списки

Циклические связные списки отличаются от обычных только одним: последний узел ссылается не в NULL, а на первый узел данного списка, то есть на «начало» списка. Пустой циклический список, таким образом, содержит единственный узел, который указывает сам на себя. При добавлении элементов, последний узел будет указывать на первый узел (рис. 9.4).

Циклические списки во многом значительно упрощают разработку алгоритмов.

а) однонаправленный связный циклический список

б) двусвязный циклический список

Рис. 9.4. Циклические списки

9.3. Стеки

Стек представляет собой упорядоченный набор элементов, доступ к которым осуществляется только с одного конца, называемого вершиной стека. Проще говоря, стек – это вид связного списка, вставку и удаление элементов которого можно совершить только с одного конца – из вершины стека. Стек организован по принципу LIFO (Last Input First Output) – “последним вошел, первым вышел”. Стек, аналогично списку, состоит из связных узлов, каждый из которых представляет собой поле данных и указатель, содержащий адрес следующего элемента. Указатель последнего элемента имеет значение NULL, чтобы тем самым обозначить конец стека (рис. 9.5).

Рис. 9.5. Стек

Над стеком выполняются две основные операции: занести элемент данных в стек – функция PUSH, и извлечь элемент данных из вершины стека – функция POP.

Ниже приведено программное описание стека. Он содержит два поля: поле данных типа char и указатель на структуру того же типа, т.е. на следующий элемент стека.

struct Stack

{

char letter;

struct Stack *nextPtr;

};

Функция помещения элемента в стек, в качестве параметров получает указатель на первый элемент или нулевой указатель, если стек не создан, и переменную, которую необходимо поместить в стек. Далее происходит выделение динамической памяти для нового элемента. И этот элемент вставляется в начало стека путем присваивания указателю на следующий элемент указателя на начало стека, а указателю на начало стека, соответственно значения указателя на новый элемент.

typedef Stack *StackPtr;

void push(StackPtr *beginPtr, char value)

{

StackPtr newPtr;

//выделение памяти под элемент

newPtr = (Stack *) malloc(sizeof(Stack));

if (newPtr != NULL)

{

newPtr->letter = value;

newPtr->nextPtr = *beginPtr; // помещение элемента

*beginPtr = newPtr; // в стек

}

else

printf("Ошибка выделения памяти!!!");

}

Функция poр получает в качестве параметров указатель на начало стека, а возвращает значение, которое оттуда извлекает, т.е. элемент данных, который находился в вершине стека. Для удаления элемента рабочему указателю присваивается значения указателя на начало стека. В свою очередь, значению указателя на начало стека присваивается значение указателя на следующий элемент стека, а динамическая память выделенная под удаляемый элемент освобождается при помощи функции free.

char pop(StackPtr *beginPtr)

{

char popValue;

StackPtr tempPtr;

tempPtr = *beginPtr;

popValue = (*beginPtr)->letter; // присваивание значения

// возвращаемого элемента

// переопределение указателя на начало стека

*beginPtr = (*beginPtr)->NextPtr;

free(tempPtr); //освобождение памяти

return popValue;

}

При использовании стека в программе, следует очистить его, когда в нем уже не будет надобности, это сэкономит машинные ресурсы.