Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Структуры данных

Матрица инцидентности

Матрица I(G) размером n x m (n - число вершин, m - число ребер/дуг графа G), (i,j)-й элемент, которой равен 1, если вершина ni инцидентна ребру eij в неориентированном графе или если ni есть начало дуги ej равен -1, если вершина ni есть конец дуги ej (только для ориентированных графов), и равен 0 в остальных случаях.

В данной задаче задается граф и строится его матрица инцидентности:

//Построение матрицы инцидентности

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

#include <iostream.h>

struct elem

{

int num; /* Номер вершины */

int suns; /* Количество сыновей */

char str[20]; /* Строка с номерами сыновей */

elem *next; /* Указатель на следующую вершину */

} *head, *w1, *w2;

int connected(int i, int j)

{

int k;

char *str1;

w2 = head;

if(i == j) return 0;

for(k=1; k<i; k++)

w2 = w2->next;

if(strchr(w2->str, j)) return 1;

return 0;

}

void main()

{

int tops;

int i,j,k,l;

char *str1;

clrscr();

printf("Введите количество вершин \n");

scanf("%d", &tops);

head = (elem *)malloc(sizeof(elem));

head->num = 1;

head->suns = 0;

head->str[0] = '\0';

head->next = NULL;

w1 = head;

for(i=2;i<=tops;i++) {

w2 = (elem *)malloc(sizeof(elem));

w2->num = i;

w2->suns = 0;

w2->str[0] = '\0';

w2->next = NULL;

w1->next = w2;

w1 = w2;

}

w1 = head;

for(i=1; i<=tops; i++) {

// clrscr();

printf("Введите количество путей из вершины

%d\n", i);

scanf("%d", &k);

for(j=1; j<=k; j++) {

printf("Введите связь %d\n", j);

scanf("%d", &l);

if((l<=0) || (l > tops)) {

printf("Такой вершины нет,

повторите попытку\n");

l = 0;

j--;

continue;

}

w1->str[w1->suns++] = l;

w1->str[w1->suns] = '\0';

if(w1->suns == 49) {

printf("Слишком много связей!");

exit(1);

}

}

w1 = w1->next;

}

clrscr();

printf("\n\n Матрица инциндентности:\n");

for(i=1; i<=tops; i++) {

printf("\n %d) ", i);

for(j=1; j<=tops; j++) {

printf("%d ", connected(i, j));

}

}

printf("\n\n Нажмите любую клавишу...");

getch();

}

Решение комбинаторных задач предполагает выделение структур сложного типа с их последующей реализацией средствами выбранного языка программирования. При этом структура данных может не зависеть от конкретных языковых конструкций (абстрактная структура данных).

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

Рассмотрим некоторые основные структуры данных.

Стеки

Стеком называется структура данных, загрузка или увеличение элементов для которой осуществляется с помощью указателя стека в соответствии с правилом LIFO (last-in, first-out - последним введен, первым выведен).

Указатель стека sp (stack pointer) содержит в любой момент времени индекс (адрес) текущего элемента, который является единственным элементом стека, доступным в данный момент времени для работы со стеком (для случая, когда указатель стека всегда задает ячейку, находящуюся непосредственно над его верхним элементом).

Начальная установка:

sp=1;

Загрузка элемента х в стек:

stack[sp]=x;

sp=sp+1;

Извлечение элемента из стека:

sp=sp-1;

x=stack[sp];

Проверка на переполнения и загрузка элемента в стек:

if(sp<=sd) {stack[sp]=x;sp=sp+1}

else// переполнение

Здесь sd - размерность стека.

Проверка наличия элементов и извлечение элемента стека:

if (sp>1){sp=sp-1;x=stack[sp]} //антипереполнение

Чтение данных из указателя стека без извлечения элемента:

x=stack[sp-1];

Очереди

Очередь - одномерная структура данных, для которой загрузка или извлечение элементов осуществляется с помощью указателей начала (head) и конца (tail) очереди в соответствии с правилом FIFO (first-in, first-out - первым введен, первым выведен).

Начальная установка:

head=1; tail=1;

Добавление элемента:

queue[tail]=x; tail=tail+1;

if(tail>qd) tail=1;

Здесь qd - размерность очереди.

Исключение элемента:

x=queue[head]; head=head+1;

if(head>qd) tail=1;

Проверка переполнения очереди и включение в нее элемента:

temp=tail+1;

if(temp=head)

{Переполнение}

else {queue[tail]=x; tail=temp}

Проверка наличия элементов и исключение элемента х:

if(head==tail) { очередь пуста}

else{ x=queue[head]; head=head+1;

if(head>qd) head=1;}

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

Связанные списки

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

Приведем основные базисные операции для работы с однонаправленным связанным списком.

Включение элемента после элемента p:

link[q]=link[p];

link[p]=q;

Здесь q - индекс элемента, который должен быть вставлен в список после элемента с индексом.

Исключение преемника элемента x:

if(link[x]!= NULL) link[x]=[link[x]]

else

{элемент не имеет преемника}

Отметим, что элемент, следующий в списке за элементом x, называется преемником элемента x, а элемент, расположенный перед элементом x, называется предшественником элемента x. Если элемент x не имеет преемника, то содержащемуся в нем указателю присваивается значение null.

Включение элемента y перед элементом x:

prev=0;

while((link[prev]!=null) && (link[prev]!=x)) do

prev=link[prev];

if (link[prev]==x) {

link[prev]=y; link[y]=x

}

else

{ элемент x не найден };

Здесь link[0] является началом списка.

Отметим, что исключение последнего элемента из однонаправленного списка связано с просмотром всего списка.

В двунаправленном связанном списке каждый элемент имеет два указателя (succlink - описывает связь элемента с преемником, predlink - с предшественником).

Приведем основные базисные операции для работы с двунаправленным связанным списком.

Включение элемента перед элементом x:

succlink[y]=x;

predlink[y]=predlink[x];

succlink[predlink[x]]=y;

predlink[x]=y;

Включение элемента y после элемента x:

succlink[y]=succlink[x];

predlink[y]=x;

predlink[succlink[x]]=y;

succlink[x]=y;

Исключение элемента x:

predlink[succlink[x]]=predlink[x];

succlink[predlink[x]]=succlink[x];

Пример 1:

/* В список помещаются цифры 1...10

Вводится число 11, сначала вставляется за цифрой 10,

затем рвется связь между 3 и 4, между ними вставляется число 11.

Пример дает навык работы:

- с динамической памятью;

- создания абстрактной структуры данных - список и

модификации списка;

- со структурами данных;

- с функциями. */

#include <stdlib.h>

#include <string.h>

#include <stdio.h>

#include <conio.h>

#include <math.h>

#include <dos.h>

struct List {

int i;

List *next;

};

/* структура данных, первое поле для хранения целого, второе поле-адрес в динамической памяти*/

List*head=NULL; /* начальный адрес*/

void Hed(int i) /* функция, которая создает очередной элемент списка */

{

if(head==NULL) {

head=(List*)malloc(sizeof(List));

head->i=1;

head->next=NULL;

} else {

struct List *p,*p1;

p=head;

while(p->next!=NULL)

p=p->next;

p1=new List;

p1->i=i;

p1->next=NULL;

p->next=p1;

}

}

int s=0;

void Print(List*p)/* вывод списка на экран */

{

printf(" %d",p->i);

if(p->next!=NULL)Print(p->next);

}

void delist()/* освобождение динамической памяти */

{

List*p;

while(head!=NULL) {

p=head;

head=head->next;

free(p);

}

}

void Vstavka(int i1,int c)

/*вставка нового элемента*/

{

List*p=head,*p1;

while(p->i!=i1)

p=p->next;

p1=new List;

p1->i=c;

p1->next=p->next;

p->next=p1;

}

void main()/* вход в программу */

{

clrscr();/* очистить экран */

for(int i=1;i<=10;i++)

Hed(i);/* создание списка */

Print(head);/* вывод списка на экран */

Vstavka(10,11);

printf("\n");

Print(head);

Vstavka(3,11);

printf("\n");

Print(head);

delist();

getch();

}

<== предыдущая лекция | следующая лекция ==>
Поиск узлов из простых чисел | Все операции со стеком
Поделиться с друзьями:


Дата добавления: 2014-01-05; Просмотров: 257; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.032 сек.