Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
312.doc
Скачиваний:
7
Добавлен:
30.04.2022
Размер:
2.14 Mб
Скачать

2.4. Организация двусвязных списков

Связанное хранение линейного списка называется списком с двумя связями или двусвязным списком, если каждый элемент хранения имеет два компонента указателя (ссылки на предыдущий и последующий элементы линейного списка).

В программе двусвязный список можно реализовать с помощью описаний:

typedef struct ndd {

float val; /* значениеэлемента */

struct ndd *n; /* указатель на следующий элемент*/

struct ndd *m; /* указатель на предыдующий элемент */

} NDD;

NDD *dl, *p, *r;

floatnov;

Графическая интерпретация метода связанного хранения списка F=< 2,5,7,1 > как списка с двумя связями приведена на рис.9.

Рис. 9. Схема хранения двусвязного списка

Вставка нового узла со значением new за элементом, определяемым указателем p, осуществляется при помощи операторов:

r=(NDD*) malloc(sizeof(NDD));

r->val=nov;

r->m=p;

r->n=p->n;

p->n=r;

Удаление элемента, следующего за узлом, на который указывает p:

r=p->n;

p->n=(p->n)->n;

((p->n)->n)->m=p;

free(r);

Связанное хранение линейного списка называется циклическим списком, если его последний указывает на первый элемент, а указатель dl – на последний элемент списка.

Схема циклического хранение списка F=< 2,5,7,1 > приведена на рис.10.

Рис. 10. Схема циклического хранения списка

При решении конкретных задач могут возникать разные виды связанного хранения.

Пусть на входе задана последовательность целых чисел B1, B2,..., Bn из интервала от 1 до 9999, и пусть Fi (1 i 9999) по возрастанию. Составить процедуру для формирования Fn в связанном хранении и возвращения указателя на его начало.

При решении задачи в каждый момент времени имеем упорядоченный список Fi и при вводе элемента Bi +1 вставляем его в нужное место списка Fi, получая упорядоченный список Fi +1. Здесь возможны три варианта: в списке нет элементов; число вставляется в начало списка; число вставляется в конец списка. Чтобы унифицировать все возможные варианты, начальный список организуем как связанный список из двух элементов <0,10000>.

Рассмотрим программу решения поставленной задачи, в которой указатели dl, r, p, v имеют следующее значение: dl указывает начало списка; p, v - два соседних узла; r фиксирует узел, содержащий очередное введенное значение in.

#include <STDIO.H>

#include <STDLIB.H>

#include <conio.h>

typedef struct str1 {

float val;

struct str1 *n;

} ND;

ND *arrange(void);

void main()

{

ND *p=arrange();

ND *buf=p;

clrscr();

while(1)

{

printf("\n %f ",p->val);

p=p->n;

if( p==buf ) return;

}

}

ND *arrange() /*формирование упорядоченного списка */

{

ND *dl, *r, *p, *v;

float in=1;

char *is;

dl=(ND*) malloc(sizeof(ND));

dl->val=0; /*первыйэлемент*/

dl->n=r=(ND*) malloc(sizeof(ND));

r->val=10000;

r->n=dl; /*последний элемент */

p=dl; // предыдущий

v=r; // следующий

while(1)

{

scanf("%s",is);

if(*is=='q') return(dl);

in=atof(is);

r=(ND*) malloc(sizeof(ND));

r->val=in;

r->n=v;

p->n=r;

p=p->n;

}

return(dl);

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]