Реферат: Разработка программ с использованием динамической памяти

ВВЕДЕНИЕ

На сегодняшний день всё большее количество людейсталкивается с компьютером, прогресс неумолимо движет нас вперёд. В данноевремя это обусловлено большими информационными потоками, и необходимообеспечивать эту отрасль специалистами информационных технологий.

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

Переменные-указатели содержат в качестве своих значенийадреса памяти. Обычно переменная содержит определенное значение. С другойстороны, указатель содержит адрес переменной, которая содержит определенноезначение. В этом смысле имя переменной отсылает к значению прямо, а указатель –косвенно. Ссылка на значение посредством указателя называется косвеннойадресацией.

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

Чтобы лучше понять указатели, рассмотрим устройствооперативной памяти компьютера. Оперативная память разделена на последовательнопронумерованные ячейки. Каждая переменная размещается в одной или несколькихпоследовательно расположенных отдельных ячейках памяти, адрес первой из нихназывается адресом переменной. Каждая ячейка в оперативной памяти занимает 1байт или 8 бит.


1. ПОСТАНОВКА ЗАДАЧИ

Задание №1:

Описать функцию, которая меняет местами первый ипредпоследний элемент непустой очереди.

Входные данные:

Запись{inf}: цел – элементы очереди;

Промежуточные данные:

kol: цел – счетчик(номера элементовочереди);

key: сим – клавиша события;

tmp: сим – временный массив символов;

Ограничения:

нет

Задание №2:

Определить количество изолированных вершин неориентированногографа, вывести их список. Сделать выбранную вершину неизолированной.

Входные данные:

Запись {v1, v2}:цел – 1-я и 2-я вершины одного ребра;

n: цел – общее количество вершин вграфе.

Промежуточные данные:

i: цел – счетчик(номера элементов1-ой очереди);

f: цел – счетчик(проверка насуществование висячих вершин);

ch: сим – клавиша события;

s,s1: сим –строки, которые нужны для проверки введенных результатов;

v [10]: сим – показатель степениданной вершины.

Ограничения:

2<=n<=5;

1<=v1<=n;

1<=v2<=n;

v1<>v2.

Выходные данные:

Запись {v1, v2}:цел – граф после удаления одной из висячих вершин.


2. ОБРАБОТКА СПИСКОВ2.1. Описание структуры списка

Линейный список — это конечная последовательность однотипныхэлементов (узлов), возможно, с повторениями. Количество элементов впоследовательности называется длиной списка, причем длина в процессе работыпрограммы может изменяться. Линейный список F, состоящий из элементов D1,D2,...,Dn,записывают в виде последовательности значений заключенной в угловые скобки F=,или представляют графически (рисунок 2.1).

D1   D2   D3  ...   Dn

Рисунок 2.1.- Изображение линейного списка

Например,F1=< 2,3,1>,F2=< 7,7,7,2,1,12 >, F3=< >. Длина списков F1,F2, F3 равна соответственно 3,6,0. В реальных языках программирования неткакой-либо структуры данных для представления линейного списка. Поэтому приработе с линейными списками важным является представление используемых впрограмме линейных списков таким образом, чтобы была обеспечена максимальнаяэффективность и по времени выполнения программы, и по объему требуемой памяти. Методыхранения линейных списков разделяются на методы последовательного и связанногохранения. При последовательном хранении элементы линейного списка размещаются вмассиве d фиксированных размеров, например, 100, и длина списка указывается впеременной l, т.е. в программе необходимо иметь объявления вида

float d [100]; int l;

Размермассива 100 ограничивает максимальные размеры линейного списка. Список F вмассиве d формируется так:

d [0] =7; d[1] =10; l=2;

Полученныйсписок хранится в памяти согласно схеме на рисунке 2.2.

 l:  2  d:  7  10     ...      [0]  [1]  [2]  [3]  [98]  [99] Рисунок 2.2. – Последовательное хранение линейного списка

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

Описаниеструктуры и указателя в этом случае может имееть вид:

typedefstruct snd /* структура элемента хранения */

{ float val;/* элемент списка */

struct snd*n; /* указатель на элемент хранения */

} DL;

DL *p; /*указатель текущего элемента */

DL *dl; /*указатель на начало списка */

Длявыделения памяти под элементы хранения необходимо пользоваться функциейmalloc(sizeof(DL)) или calloc(l,sizeof(DL)). Формирование списка в связанномхранении может осуществляется операторами:

p=malloc(sizeof(DL));

p->val=10;p->n=NULL;

dl=malloc(sizeof(DL));

dl->val=7;dl->n=p;

В последнемэлементе хранения (конец списка) указатель на соседний элемент имеет значениеNULL. Получаемый список изображен на рисунке 2.3.


/> 

Рисунок 2.3.– Связное хранение линейного списка

2.2. Операции над элементами списка

При простом связанном хранении каждый элемент спискапредставляет собой структуру graf, состоящую из двухэлементов: v — предназначен для хранения элемента списка, next- для указателя на структуру, содержащую следующий элемент списка. На первыйэлемент списка указывает указатель head. Для всехопераций над списком используется описание:

typedef struct graf

{ int v;

struct graf* next;

} Graf;

Graf *g, *head, *teil;

Для реализации операций могут использоваться следующиефрагменты программ:

1) определить первый элемент в линейном списке (рисунок 2.4):

printf(«v=»);

scanf("%d",&head->v);

head->next=0;

teil->next=0;

teil=head;

/>


head: NULL

Рисунок 2.4. – Создание первого элемента в списке

2) вставить дополнительный элемент после указанного узла(рисунок 2.5):

printf(«v=»);

scanf("%d",&g->v);

teil->next=g;

/> teil=teil->next;

head: NULL

Рисунок 2.5. – Вставка дополнительного элемента

3) печать всех элементов списка:

g=head;

i=0;

while(g! =NULL)

{

i++;

printf(«Эллемент%d:%d\n», i,g->v1);

g=g->next;

}

2.3. Описание программной реализации

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

Очередь аналогична очереди людей в супермаркете: первыйклиент в ней обслуживается первым, а другие клиенты занимают очередь с конца иожидают, когда их обслужат. Узлы очереди удаляются только из головы очереди, апомещаются в очередь только в ее хвост. По этой причине, очередь – этоструктура данных типа «первым вошел – первым вышел» (first-in, first-out – FIFO). У очередей имеетсямножество применений в вычислительных системах. У большинства компьютеровимеется только один процессор, поэтому в один и тот же момент времени может бытьобслужен только один пользователь. Запросы остальных пользователей помещаются вочередь. Каждый запрос постепенно продвигается в очереди вперед по мере того,как происходит обслуживание пользователей. Запрос в начале очереди являетсяочередным кандидатом на обслуживание.

Первые четыре функции для формирования очереди похожи междусобой: первые две из них: vvod1 и vvod2нужны для созданий первых элементов двух очередей. Две остальные: dobavl1 и dobavl2, для добавленияновых элементов в уже созданные нами очереди. Последняя функция: proga, содержит первые четыре и ряд новых возможностей, вкоторый входят: возможность вывода на экран всех элементов очередей, а такжевозможность проверки на вхождение всех элементов первой очереди во вторую. Таккак структуры можно сравнивать только поэлементно в данной функции в циклекаждый элемент сравнивается с отдельными элементами второй очереди, еслиэлемент первой очереди встречается во второй, значит что этот элемент входит вовторую очередь. В конце расчетов на экран пользователю выводитсясоответствующее сообщение о том, есть ли вхождение одной очереди в другую илиего нет.

2.3.1. Описание процедур и функций языка

void *malloc(size_t size) – данная функция используется для выделения памяти изкучи в байтах. Для таких информационных структур, таких как деревья и спискивыделение памяти происходит таким же способом

void free(void *block)– данная функция очищает память, которая была выделена такими функциями как calloc, malloc или realloc.


2.3.2. Описание созданных функций для работы со списками

void vvod1() – данная функция создает первый элемент очереди подномером 1 и, используя стандартную функцию malloc,выделят определенное количество памяти под этот первый элемент;

void dobavl1() – функция в цикле, до нажатия клавиши Esc, каждый раз добавляет новый элемент 1-ой очереди ивыделяет под него память.

void vvod2() – данная функция создает первый элемент очереди подномером 2 и, используя стандартную функцию malloc,выделят определенное количество памяти под этот первый элемент;

void dobavl2() – функция в цикле, до нажатия клавиши Esc, каждый раз добавляет новый элемент 2-ой очереди ивыделяет под него память.

void proga() – эта функция содержит в себе все выше перечисленные,поэтому она создает первые элементы 1-ой и 2-ой очередей и добавляет в нихновые элементы. Также эта функция выводит на экран полученные очереди, то естьвыводит на экран все элементы двух очередей, после чего функция производитсравнение: входит ли 1-я очередь во 2-ю, и выводит результат на экран.


3. ИСПОЛЬЗОВАНИЕ ДИНАМИЧЕСКИХ СТРУКТУР ПРИ РАБОТЕ С ГРАФАМИ3.1. Способы представления графов

Для представления графа можно использовать матрицусмежности, матрицу инцидентности либо представить его списком дуг.

Основные способы представления (задания) графов:

1) перечисление множеств V (вершин) иE (ребер), задающих граф. G = (V, E);

2) матричные способы описания;

Пусть G = (V,E), |V| = p,а |E| = q, тогда:

a) матрица смежности – квадратнаяматрица />,где />

b) матрица инцидентности –прямоугольная матрица />.

/>

3) список дуг:

Пример: задан граф G = (V, E), где V= {v1, v2, v3,v4}, E = {v1v2, v2,v3, v1v3, v1v4, v3,v4} ={e1, e2, e3,e4, e5}. Рисунок 3.1.

/> v2

 v1

v3

v4

Рисунок 3.1. – Пример построения графа

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

/>


head: NULL

Рисунок 3.2. – Пример связности ребер графа

3.2. Операции над графами

При связанном хранении каждая вершина графа представляетсобой структуру graf, состоящую из двух элементов: v1,v2 — предназначены для хранения вершин графа, next — для указателя на структуру, содержащую следующуювершину графа. На первые элементы графа указывает указатель head.Для всех операций над графом используется описание:

typedef struct graf

{ int v1,v2;

struct graf* next;

} Graf;

Graf *g, *head, *temp;

Для реализации операций могут использоваться следующиефрагменты программ:

1) определить первый элемент в линейном списке (рисунок 3.1):

printf(«v1=»);

/>scanf("%d",&head->v1);

head->next=0;

 NULL

 head NULL

Рисунок 3.3– Создание первого элемента в графе

2) вставить дополнительный элемент после указанного узла(рисунок 3.2):

printf(«v=»);

scanf("%d",&g->v1);

/>g->next=head;

head=g;

 

 ……

 head NULL

Рисунок 3.4– Вставка дополнительного элемента

3) печать всех элементов списка:

printf(«Ребра графа: \n»);

g=head;

i=0;

while(g! =NULL) {

i++;

printf(«РЕБРО%d:v1=%d v2=%d\n», i,g->v1,g->v2);

g=g->next; }

4) удаление ребра:

/>

Удалить ребро означает разрушить связь между вершинами,которые являются для данного графа концевыми.

5) удаление вершины:

if((head->v1==i) ||(head->v2==i))

head=head->next;

else{

temp=head;

g=head->next;

while(g) {

if((g->v1==i) ||(g->v2==i)) {

temp->next=g->next;

free(g);

break; }

temp=g;

g=g->next; }}

Удалить вершину означает разрушить связь со смежными ейвершинами и создать новую связь уже без этой вершины. Схема удаления вершины графа,следующей за узлом, на который указывает р находится на рисунке 3.3.

/> 

Рисунок 3.5– Схема удаления вершины графа

3.3. Описание программной реализации

Данная программа реализована при помощи всего двух функций,которые в полной мере выполняют поставленную перед программой задачу. Задачейявляется поиск висячих вершин в графе и удаление одной из них, которую укажетпользователь.

Висячей вершиной графа называется такая вершина, степенькоторой равна единице, то есть вершина, которая имеет всего лишь одно смежноеей ребро. Граф, содержащий висячую вершину изображен на рисунке 3.4.

3 2

/> 1

4 5

Рисунок 3.6– Изображение графа, содержащего висячую вершину

Степени вершин в данном графе таковы: 11, 23, 32, 42, 52, изэтого следует, что изолированной вершиной является вершина под номером 1.

Список ребер до удаления висячей вершины в этом графе будетиметь вид: ребо1: 1-2, ребро2: 2-3, ребро3: 3-4, ребро4: 4-5 и ребро5: 5-2.

После удаления единственной висячей список ребер примет вид:ребро1: 2-3, ребро2: 3-4, ребро3: 4-5 и ребро4: 5-2.

Каждая функция данной программы полностью выполняетпоставленную перед ней задачу. Первая функция klavасоздает первую вершину графа и предлагает пользователю дополнить граф другимивершинами. Функция реализована таким способом, что пользователь вводит вершиныпопарно, то есть вводит вершины одного ребра. Вторая функция raschetпроизводит поиск висячих вершин графа и, если они имеются, предлагаетпользователю выбрать одну из них для ее удаления и удаления смежного ей ребра. Взавершение программы на экран пользователю выводится обновленный список ребервведенного графа.

3.3.1. Описание процедур и функций языка

void *malloc(size_t size) – данная функция используется для выделения памяти изкучи в байтах. Для таких информационных структур, таких как деревья и спискивыделение памяти происходит таким же способом

void free(void *block)– данная функция очищает память, которая была выделена такими функциями как calloc, malloc или realloc.

3.3.2. Описание созданных функций для работы с динамическойпамятью, графами

Создание и поддержание динамических структур данных требуетдинамического распределения памяти: возможности в процессе выполнения программыувеличивать область памяти для хранения новых узлов и освобождать ресурсыпамяти, в которых уже нет необходимости. Пределы динамического выделения памятиограничены только объемом доступной физической памяти или доступной виртуальнойпамяти в системах с виртуальной памятью. Впрочем, часто эти пределы намногоменьше из-за того, что свободная память делится при совместном доступе к ней многихпользователей.

void klava() – данная функция является универсальной, так какизначально она создает первый элемент (первую вершину графа), после чегопользователю предлагается дополнить граф новыми элементами (вершинами). Функцияиспользует стандартную функцию для выделения памяти языка С: malloc.

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


ВЫВОДЫ

Желание каждого программиста быть востребованным ставитперед ним определенную цель: идти в одну ногу со временем. С каждым годом этоделать становиться все сложнее и сложнее, так как за определенные промежуткивремени темпы развития компьютерных технологий постоянно увеличиваются. Задача,которую ставит перед собой программист при разработке нового продукта остаетсянеизменной уже на протяжении долгого времени: получение максимальногорезультата при минимуме затрат времени и средств. Выполнение данной задачистановится возможной только при постоянном самосовершенствовании исамообразовании программиста.

Задание, выданное на летнюю практику, поставило определенныезадачи:

1) Научится создавать связные структуры данных, используяуказатели;

2) научится создавать и манипулировать динамическимиструктурами данных, такими как связные списки, очереди и стеки;

3) понять работу различных приложений со связнымиструктурами данных.

Решение выданного задания было реализовано с помощью языкапрограммирования С.

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

Вот почему именно язык С был выбран автором для реализацииданной задачи.

Структуры – это составные типы данных, построенные сиспользованием других типов. Классы в С++ являются естественным продолжениемструктуры struct в С. Вот почему детальное изучениеэтого раздела является таким необходимым для дальнейшего изучения других языковпрограммирования. Так как прежде чем рассматривать специфику разработки классовна С++ нужно более глубоко разобраться со структурами в С.


Приложение А

ЛИСТИНГ ПРОГРАММЫ

Задание №1:

#include<stdio. h>

#include<conio. h>

#include<alloc. h>

#include<string. h>

#include<stdlib. h>

// ------------<Структура>---------

typedef struct sp

{

char inf [100];

struct sp *next;

} sp;

sp *g,*head,*teil;

// -----------</Структура>---------

void titl()

{

clrscr();

gotoxy(20,1);

printf(«МИHИСТЕРСТВО ОБРАЗОВАHИЯ И HАУКИ УКРАИHЫ»);

gotoxy(12,2);

printf(«Донецкий государственный институтискусственного интеллекта»);

gotoxy(27,8);

printf(«Здание на летнюю практику #1»);

gotoxy(35,9);

printf(«по дисциплине: „);

gotoxy(17,10);

printf(“\»Основы программирования иалгоритмические языки. \"");

gotoxy(50,15);

printf(«Выполнил: „);

gotoxy(50,16);

printf(“студент группы ПО-05г»);

gotoxy(50,17);

printf(«Пивоваров Артем Генадиевич»);

gotoxy(50, 19);

printf(«Проверил: „);

gotoxy(50, 20);

printf(“асс. МамбетоваЛилия Сергеевна»);

gotoxy(2,25);

printf(«Для продолжения нажмите любую клавишу… „);

getch();

clrscr();

gotoxy(15,10);

printf(“ЗАДАHИЕ: „);

gotoxy(10,12);

printf(“ Описать функцию, которая в списке меняетместами»);

gotoxy(10,13);

printf(«первый и предпоследний элементы. „);

gotoxy(2,25);

printf(“Для продолжения нажмите любую клавишу… „);

getch();

}

void program()

{

int kol=1;

char key;

clrscr();

printf(“Введите элементы стрруктуры: \n»);

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

g=head;

printf(«Введите%i-элемент: »,kol);

scanf("%s",&g->inf);

g->next=0;

teil->next=0;

teil=head;

// --------Ввод остальных эл-тов структуры--------------

kol++;

printf(«Введите%i-элемент: »,kol);

g=(sp*) malloc(sizeof(sp));

scanf("%s",&g->inf);

g->next=0;

teil->next=g;

teil=teil->next;

do

{

if (key! =27)

{

kol++;

printf(«Введите%i-элемент: »,kol);

g=(sp*) malloc(sizeof(sp));

scanf("%s",&g->inf);

g->next=0;

teil->next=g;

teil=teil->next;

}

printf(«Для прекращения ввода нажмите ESC; Дляпродолжения любую клавишу\n»);

key=getch();

}

while (key! =27);

printf(«Вы ввели такие элементы: \n»);

g=head;

kol=0;

while (g! =0)

{

kol++;

printf(«Эллемент%i=%s\n»,kol,g->inf);

g=g->next;

}

getch();

}

void zamena()

{

char *tmp;

g=head;

while (g->next! =NULL)

{

if (g->next->next==NULL)

{

strcpy(tmp,g->inf);

strcpy(g->inf,head->inf);

strcpy(head->inf,tmp);

}

g=g->next;

}

// --------------Вывод результата----------------

g=head;

int kol=1;

printf("\nРезультат: ");

while (g! =NULL)

{

printf("\n%i-й элемент равен:%s",kol,g->inf);

kol++;

g=g->next;

}

getch();

}

void cleen()

{

g=head;

while (g! =NULL)

{

free(g);

g=g->next;

}

}

void main()

{

titl();

program();

zamena();

cleen();

}

Задание №2:

// --------------------------------Библиотеки--------------------------------

#include <stdio. h>

#include <conio. h>

#include <alloc. h>

#include <string. h>

#include <stdlib. h>

// --------------------------------------------------------------------------

// ===============

char *fname [12];

FILE *in,*out;

int n, i,j;

int v [10];

char s [6],s1 [6];

// ===============

// ***********************************

typedef struct graf

{

int v1,v2;

struct graf *next;

} Graf;

Graf *g,*head;

// ***********************************

// --------------------------------Реквизиты---------------------------------

// --------------------------------------------------------------------------

void tit()

{

clrscr();

gotoxy(20,1);

printf(«МИHИСТЕРСТВООБРАЗОВАHИЯ И HАУКИ УКРАИHЫ»);

gotoxy(12,2);

printf(«Донецкий государственный институтискусственного интеллекта»);

gotoxy(27,8);

printf(«Здание на летнюю практику #2»);

gotoxy(35,9);

printf(«по дисциплине: „);

gotoxy(17,10);

printf(“\»Основы программирования иалгоритмические языки. \"");

gotoxy(50,15);

printf(«Выполнил: „);

gotoxy(50,16);

printf(“студент группы ПО-05г»);

gotoxy(50,17);

printf(«Пивоваров Артем Генадиевич»);

gotoxy(50, 19);

printf(«Проверил: „);

gotoxy(50, 20);

printf(“асс. МамбетоваЛилия Сергеевна»);

gotoxy(2,25);

printf(«Для продолжения нажмите любую клавишу… „);

getch();

return;

}

// --------------------------------------------------------------------------

// --------------------------------Задание-----------------------------------

// --------------------------------------------------------------------------

void work_window()

{

clrscr();

gotoxy(35,1);

printf(“ЗАДАHИЕ: „);

gotoxy(12,2);

printf(“ Определитьколичество»);

gotoxy(12,3);

printf(" изолированных вершин нориентированногографа,");

gotoxy(12,4);

printf(«вывести их список. Сделать выбраную вершинунеизолированной! \n»);

return;

}

// --------------------------------------------------------------------------

// --------------------------------------------------------------------------

// ----------------------Ввод данных склавиатуры---------------------------

void klava()

{

do

{

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

scanf("%s",&s);

n=atoi(s);

itoa(n,s1,10);

if((n<2) ||(n>5))

printf(«Ошибка! Выход из диапазона: '2<n<=5'\n»);

}

while((n<2) ||(n>5) ||strcmp(s,s1));

// --------------------------------------------------------------------------

for (i=0; i<n; i++)

v [i] =0;

// --------------------------------------------------------------------------

// --------------------Ввод первого элементасписка--------------------------

// --------------------------------------------------------------------------

printf(«Введите ребра графа: \n»);

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

// ======================================================

do

{

printf(«v1=»);

scanf("%s",&s);

head->v1=atoi(s);

itoa(head->v1,s1,10);

if (((head->v1) <1) ||((head->v1) >n))

printf(«Ошибка! Выход из диапазона: '1<v1<=n'\n»);

}

while(((head->v1) <1) ||((head->v1)>n) ||strcmp(s,s1));

// ======================================================

do

{

printf(«v2=»);

scanf("%s",&s);

head->v2=atoi(s);

itoa(head->v2,s1,10);

if (((head->v2) <1) ||((head->v2) >n))

printf(«Ошибка! Выход из диапазона: '1<v2<=n'\n»);

}

while(((head->v2) <1) ||((head->v2)>n) ||strcmp(s,s1));

// ======================================================

head->next=NULL;

// --------------------------------------------------------------------------

// -------------------Ввод остальных элементовсписка------------------------

// --------------------------------------------------------------------------

char ch=1;

while(ch! =27)

{

printf(«Хотите продолжить ввод вершин? \n»);

ch=getch();

if (ch! =27)

{

g=(Graf *) malloc(sizeof(Graf));

// ======================================================

do

{

printf(«v1=»);

scanf("%s",&s);

g->v1=atoi(s);

itoa(g->v1,s1,10);

if (((g->v1) <1) ||((g->v1) >n))

printf(«Ошибка!Выход из диапазона: '1<v1<=n'\n»);

}

while(((g->v1) <1) ||((g->v1) >n)||strcmp(s,s1));

// ======================================================

do

{

printf(«v2=»);

scanf("%s",&s);

g->v2=atoi(s);

itoa(g->v2,s1,10);

if (((g->v2) <1) ||((g->v2) >n))

printf(«Ошибка!Выход из диапазона: '1<v2<=n'\n»);

}

while(((g->v2) <1) ||((g->v2) >n)||strcmp(s,s1));

// ======================================================

g->next=head;

head=g;

}

}

}

// -------------------------------------------------------------------------

// -------------------------------------------------------------------------

// -------------------------------------------------------------------------

int raschet()

{

printf(«Ребра графа: \n»);

g=head;

i=0;

while(g! =NULL)

{

i++;

printf(«РЕБРО%d:v1=%d v2=%d\n», i,g->v1,g->v2);

g=g->next;

}

// --------------------------------------------------------------------------

// --------------Просмотр графа и поиск изолированыхвершин------------------

// --------------------------------------------------------------------------

g=head;

while(g! =NULL)

{

v [g->v1-1] ++;

v [g->v2-1] ++;

g=g->next;

}

int f=0;

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

printf(«v [%d] =%d\n», i,v [i-1]);

printf(«Изолированные вершины: „);

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

if (v [i-1] ==0)

printf(“%d », i);

else

if (v [i-1]! =0)

f=f+1;

// ********************************************

if (f==n)

{

printf("\nИзолированных вершин HЕТ! ");

// ----------------------------Сохранениев файл------------------------------

i=0;

if ((out=fopen(«1. txt»,«w»)) == NULL)

{

printf(«Ошибка открытия входного файла! \n»);

return 1;

}

g=head;

while(g! =NULL)

{

i++;

fprintf(out,«Изолированных вершин HЕТ! „);

fprintf(out,“РЕБРО%d: v1=%d v2=%d\n», i,g->v1,g->v2);

g=g->next;

}

fclose(out);

// --------------------------------------------------------------------------

getch();

exit(1);

}

else

// --------------------------------------------------------------------------

// -----------------Добавление вершины в головусписка-----------------------

// --------------------------------------------------------------------------

printf("\nКакую вершину вы хотите сделать неизолированной? \n");

// ======================================================

do

{

printf(«Укажите вершину: „);

scanf(“%s»,&s);

i=atoi(s);

itoa(i,s1,10);

if ((i>n) ||(i<1) ||(v [i-1]! =0))

printf(«Ошибка!\n»);

}

while((v [i-1]! =0) ||strcmp(s,s1) ||(i>n)||(i<1));

// ======================================================

g=(Graf *) malloc(sizeof(Graf));

g->v1=i;

g->v2=head->v1;

g->next=head;

head=g;

printf(«Ребра графа после добавления одного ребра: \n»);

g=head;

i=0;

while(g! =NULL)

{

i++;

printf(«РЕБРО%d:v1=%d v2=%d\n», i,g->v1,g->v2);

g=g->next;

}

// ********************************************

// ----------------------------Сохранение вфайл------------------------------

i=0;

if ((out=fopen(«1. txt»,«w»)) == NULL)

{

printf(«Ошибка открытия входного файла! \n»);

return 1;

}

g=head;

while(g! =NULL)

{

i++;

fprintf(out," РЕБРО%d: v1=%d v2=%d\n", i,g->v1,g->v2);

g=g->next;

}

fclose(out);

}

// --------------------------------------------------------------------------

// --------------------------------------------------------------------------

// --------------------------------------------------------------------------

void main()

{

clrscr();

// ==============

tit();

work_window();

klava();

raschet();

// ==============

getch();

}

еще рефераты
Еще работы по информатике, программированию