
1-1 Программирование С++ / html / modules / 028 / content / content1
.htmlІнформатика — Теорія — Види динамічних структур Автори
|
Контакти
|
Підсистема допомоги
|
Методичні вказівки
|
Анотація
|
Назад
ІнформатикаДинамічні структури даних : Види динамічних структурЗміст курсу
Вступ
Теорія
Види динамічних структур
Інші види динамичних структур
Практика
Практичне заняття
Лабораторна робота
Поточна перевірка знань
Динамічні структури даних
Версія для друку
Види динамічних структур Лінійні списки Лінійний список - це скінченна послідовність однотипних елементів (вузлів). Кількість елементів у цій послідовності називається довжиною списку. Наприклад :F=(1,2,3,4,5,6) - лінійний список, його довжина 6. При роботі зі списками дуже часто доводиться виконувати такі операції :- додавання елемента в початок списку; - вилучення елемента з початку списку; - додавання елемента в будь-яке місце списку; - вилучення елемента з будь-якого місця списку; - перевірку, чи порожній список; - очистку списку; - друк списку. Основні методи зберігання лінійних списків поділяються на методи послідовного та зв'язаного зберігання. Метод послідовного зберігання списків ґрунтується на використанні масиву елементів деякого типу та змінної, в якій зберігається поточна кількість елементів списку. #define MAX 100 /* максимально можлива довжина списку */typedef struct { int x; /* тут потрібно описати структуру елементів списку*/} elementtype;typedef struct { elementtype elements[MAX]; int count;} listtype; У вищенаведеному фрагменті програми описуються типи даних elementtype (визначає структуру елемента списку) та listtype (містить масив для зберігання елементів та змінну для зберігання поточного розміру списку). Наводимо приклади реалізації функцій для виконання основних операцій над списками.1. Ініціалізація списку (робить список порожнім). void list_reset(listtype *list){ list->count=0;}
2. Додавання нового елементу у кінець списку.void list_add(listtype *list,elementtype element){ if (list->count==MAX) return; list->elements[list->count++]=element;
}
3. Додавання нового елементу в задану позицію pos.
Рисунок 1 - Додавання нового елементу в задану позицію
void list_insert(listtype *list,int pos,elementtype element){ int j; if (pos<0||pos>list->count||pos>=MAX) return; for (j=list->count;j>pos;j--) { list->elements[j]=list->elements[j-1]; } list->elements[j]=element; list->count++;}
4. Вилучення елемента з номером pos.
Рисунок 2 - Схема вилучення елемента зі списку
void list_delete(listtype *list,int pos){ int j; if (pos<0||pos>list->count) return; for (j=pos+1;j<list->count;j++) { list->elements[j-1]=list->elements[j]; } list->count--;Ї
5. Отримання елемента з номером pos.int list_get(listtype *list,int pos,elementtype *element){ if(pos<0||pos>list->count) { return 0; } *element=list->elements[pos]; return 1;}
При послідовному зберіганні списків за допомогою масивів елементи списку зберігаються в масиві. Така організація дозволяє легко переглядати вміст списку та додавати нові елементи в його кінець. Але такі операції, як вставка нового елемента в середину списку чи вилучення елементу з середини списку потребують зсуву всіх наступних елементів. При збільшенні елементів масиву кількість операцій, потрібна для впорядкування списку, стрімко зростає.
Зв'язане зберігання лінійних списків. Найпростіший спосіб зв'язати множину елементів - зробити так, щоб кожний елемент містив посилання на наступний. Такий список називається односпрямованим (однозв'язаним). Якщо додати в такий список ще й посилання на попередній елемент, то отримаємо двозв'язаний список. А список, перший та останній елементи якого зв'язані, називається кільцевим.
Рисунок 3 - Схематична структура однозв'язаного(а), двозв'язаного(б) та кільцевого списку(в)
Рисунок 3 - Схематична структура односпрямованого(а), двоспрямованого(б) та кільцевого списку(в)
Структуру даних для зберігання однозв'язаного лінійного списку можна описати таким чином .typedef long elemtype;typedef struct node { elemtype val; node *next;} list;
В даному фрагменті програми описуються декілька типів даних.elemtype - визначає тип даних лінійного списку. Можна використовувати будь-який стандартний тип даних, включаючи структури.list - визначає структуру елемента лінійного списку (val - значення, яке зберігається у вузлі, next - покажчик на наступний вузол).
Рисунок 4 - Схематичне зображення однозв'язаного лінійного списку
Реалізація основних операцій.1. Включення елемента в початок списку.
Рисунок 5 - Схема дії операції включення елемента в початок списку
list *addbeg(list *first, elemtype x){ list *vsp; vsp = (list *) malloc(sizeof(list)); vsp->val=x; vsp->next=first; first=vsp; return first;}
2. Видалення елемента з початку списку.
Рисунок 6 - Схема дії операції видалення елемента, який був напочатку
list *delbeg(list *first){ list *vsp; vsp=first->next; free(first); return vsp;}
3. Включення нового елемента у список. list *add(list *pred, elemtype x){ list *vsp; vsp = (list *) malloc(sizeof(list)); vsp->val=x; vsp->next=pred->next; pred->next=vsp; return vsp;}
4. Видалення елемента зі списку.
Рисунок 7 - Схема вилучення елементу зі списку
elemtype del(list *pred){ elemtype x; list *vsp; vsp=pred->next; pred->next=pred->next->next; x=vsp->val; free(vsp); return x;}
5. Друк значень списку.void print(list *first){ list *vsp; vsp=first; while (vsp) { printf("%i\n",vsp->val); vsp=vsp->next; }}
6. Перевірка, чи порожній список.int pust(list *first){ return !first;}
7. Знищення списку.list *kill(list *first){ while (!pust(first))
first=delbeg(first); return first;}
Двозв'язані списки Організація двозв'язних списків.
Зв'язане зберігання лінійного списку називається списком із двома зв'язками або двоспрямованим списком, якщо кожен елемент зберігання має два компоненти покажчика (посилання на попередній і наступний елементи лінійного списку).
У програмі двоспрямований список можна реалізувати за допомогою описів:
typedef struct ndd
{
float val; /* значення елемента */
struct ndd * n; /* покажчик на наступний елемент */
struct ndd * m; /* покажчик на попередній елемент */
} NDD;
NDD * dl, * p, * r;.
Графічна інтерпретація методу зв'язаного зберігання списку F=<2,5,7,1> як списку із двома зв'язками наведена на рис. 8.
Рисунок 8 - Схема двоспрямованого списку
1. Вставка нового вузла зі значенням 4.5 за елементом, обумовленим покажчиком p, здійснюється за допомогою операторів.
r=malloc(NDD);
r->val=4.5;
r->n=p->n;
p->n=r;
. r->m=p;
2. Видалення елемента, що знаходиться за вузлом, на який указує p.
p->n=(p->n)->n;
( (p->n)->n )->m=p;
free(r);
© 2008 ХНУРЭ, Інформатики, Сінельнікова Т.Ф., informatika@kture.Kharkov.uaРозроблено за допомогою LERSUS