Читайте данную работу прямо на сайте или скачайте

Скачайте в формате документа WORD


Двунаправленный динамический список

Задание

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

В программном изделии предусмотреть работу со списком, которая включает в себя:

1.     Ввод данных;

2.     Удаление данных из списка;

3.     Вывод списка на дисплей;

4.     Сортировку списка по фамилии.

Написать программное изделие на двух языках программирования: C, Pascal.

Описание алгоритма программы со структурой данных

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

Выбор из главного меню одной из следующих функций:

) Добавить;

б) далить;

в) Просмотреть;

г) Сортировать;

д) Выход.

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

При выборе функции Выход работа программы завершается.

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

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

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

При выборе функции Сортировать, происходит сортировка списка по фамилии. Если в списке встречаются две одинаковые фамилии, тогда сравниваются имена; при совпадении имён сравниваются отчества.

Описание программы

Для реализации динамического списка в программе применён тип казателей, указывающий на запись ФInformФ, содержащую фамилию ФfamФ, имя ФnameФ, отчество ФfanemФ, день рождения ФbethdayФ, знак зодиака ФzodiakФ и указатели на следующий ФnextФ и предыдущий ФprevФ элементы списка.

С помощью этого типа ФUkazatФ описаны переменные: УtempФ - для хранения казателя на текущий элемент; УfirstФ - для хранения казателя на первый элемент в списке; УcutФ - для хранения на последний элемент в списке. Переменная УchФ используется для выбора процедуры; УsФ, УsФ, УnФ - для вычисления знака зодиака; УmФ - для проверки словия, при сортировке; УffamФ, УfnameФ, УffanemФ - для временного хранения фамилии, имени, отчества, при далении элемента из списка.

Программа начинает выполняться с присвоения казателю на первый элемент (first) значения УnilФ. После этого пользователю предлагается выбрать действие: л1-Добавить, л2-Удалить, л3-Просмотреть, л4-Сортировать, л0-Выход. В зависимости от того, какое действие выберет пользователь, начнёт выполняться та или иная процедура, или произойдёт выход из программы. Это реализовано с помощью операции выбора УcaseФ.После выполнения некоторой процедуры пользователю вновь предлагается выбрать одно из вышеуказанных действий, пока не будет выбран выход из программы. Это реализовано с помощью цикла Уrepeat untilФ.

Процедура добавления УDobavФ.

Сначала выделяется память под текущий элемент (new(temp)), затем в этот элемент записывается фамилия, имя, отчество и дата рождения. По дате рождения вычисляется знак зодиака. Для этого в s2 записывается число рождения, в s1 первые три буквы месяца рождения, затем, путём сравнения этих переменных с числами и частями слов находится соответствующий знак зодиака, и заносится в текущий элемент. После ввода информации, проверяется наличие элементов в списке. Если они отсутствуют, то в текущем элементе, указателям на следующий (next) и предыдущий (prev) элементы присваивается значение УnilФ; казатель на сам элемент (temp) присваивается указателям на первый (first) и последний (cut) элементы в списке. Если список не пустой, то в текущем элементе, казателю на следующий элемент (next) присваивается значение УnilФ, а указателю на предыдущий элемент (prev) присваивается казатель на последний элемент (cut) в списке; казателю на следующий элемент (next) последнего элемента в списке и казателю на последний элемент (cut) присваивается указатель на текущий элемент (temp). После чего процедура добавления завершается.

Процедура даления УUdalФ.

В этой процедуре сначала проверяется наличие элементов в списке. Если список пуст, то выводится сообщение: Таблица пуста. Если же список содержит элементы, то пользователю предлагается ввести фамилию, имя и отчество даляемого, записывая их в ffam, fname, ffanem соответственно. После происходит поиск даляемого элемента в списке. Это реализовано с помощью цикла, который выполняется, пока элемент не найден или не просмотрен весь список. Если искомый элемент отсутствует, то выводится сообщение: Такого нет. Если же искомый элемент найден, то текущий казатель (temp) показывает на него, и происходит его даление.

Если указатели на первый (first) и последний (cut) элементы не равны, то происходит поиск местонахождения элемента в списке. Если внутри текущего элемента казатель на предыдущий элемент (prev) равен nil, тогда указателю на предыдущий элемент (prev) внутри следующего за текущим элементом присваивается казатель на предыдущий элемент внутри текущего, казателю на первый элемент (first) в списке присваивается казатель на следующий элемент. Если внутри текущего элемента казатель на следующий элемент (next) равен nil, тогд казателю на следующий элемент (next) внутри предыдущего перед текущим элементом присваивается указатель на следующий элемент внутри текущего, казателю на последний элемент (cut) в списке присваивается казатель на предыдущий элемент. Если текущий элемент оказался лвнутри списка, тогда казателю на следующий элемент (next) внутри предыдущего перед текущим элементом присваивается указатель на следующий элемент внутри текущего, казателю на предыдущий элемент (prev) внутри следующего за текущим элементом присваивается казатель на предыдущий элемент внутри текущего.

Если же казатели на первый (first) и последний (cut) элементы равны, то казателю на первый элемент в списке (first) присваивается nil.

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

Процедура просмотра УProsmФ.

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

Сначала на дисплей выводится шапка таблицы, содержащая: Фамилия Имя Отчество, Дата рождения и Знак зодиака. После вывода шапки проверяется наличие элементов в списке.

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

Если список окажется пуст, то выводится сообщение: Таблица пуста.

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

Процедура сортировки УSortirФ.

Для этой процедуры применена локальная переменная УtmpФ типа УukazatФ. Здесь сначала проверяется наличие элементов в списке.

Если список содержит элементы, то переменной УmФ присваивается значение УtrueФ, затем выполняется цикл, пока Уm=trueФ. В цикле переменной УmФ присваивается значение УfalseФ, указателю на текущий элемент (temp) присваивается казатель на первый элемент в списке (first), и выполняется вложенный цикл, пока казатель на следующий элемент внутри текущего не равена УnilФ. В этом цикле проверяется какой элемент больше.

Если текущий элемент окажется больше чем следующий за ним элемент, тогда переменной УmФ присваивается значение УtrueФ, и проверяется местонахождение текущего элемента в списке. Если он окажется в начале списка, то казателю на первый элемент в списке (first) присваивается казатель на следующий элемент за текущим, иначе казателю на следующий элемент (next) внутри предыдущего перед текущим элементом присваивается указатель на следующий элемент внутри текущего. Если же текущий элемент окажется в конце списка, тогда казателю на последний элемент в списке присваивается казатель на текущий элемент, локальной переменной УtmpФ присваивается значение УnilФ, иначе казателю на предыдущий элемент (prev) следующего элемента после следующего за текущим элементом присваивается казатель на текущий элемент, локальной переменной (tmp) присваивается казатель на следующий элемент после следующего за текущим элементом. После выяснения местоположения и выполнения некоторых команд, казателю на следующий элемент после следующего за текущим элементом присваивается казатель на текущий элемент, казателю на предыдущий элемент следующего за текущим элементом присваивается казатель на предыдущий элемент перед текущим; внутри текущего элемента казателю на предыдущий перед текущим присваивается казатель на следующий элемент за текущим, и казателю на следующий элемент за текущим присваивается локальная переменная УtmpФ. Если же текущий элемент окажется не больше чем следующий за ним элемент, тогда казателю на текущий элемент (temp) присваивается казатель на следующий за ним элемент (next). На этом выполнение вложенного цикла завершается.

Переменной УmФ снова присваивается значение УfalseФ, казателю на текущий элемент (temp) присваивается казатель на последний элемент в списке (cut), и выполняется ещё один вложенный цикл, пока казатель на предыдущий элемент внутри текущего не равена УnilФ. В этом цикле проверяется какой элемент меньше.

Если текущий элемент окажется меньше чем предыдущий перед ним элемент, тогда переменной УmФ присваивается значение УtrueФ, и проверяется местонахождение текущего элемента в списке. Если он окажется в конце списка, то казателю на последний элемент в списке (cut) присваивается казатель на предыдущий элемент перед текущим, иначе казателю на предыдущий элемент (prev) внутри следующего за текущим элементом присваивается указатель на предыдущий элемент внутри текущего. Если же текущий элемент окажется в начале списка, тогда казателю на первый элемент в списке присваивается казатель на текущий элемент, локальной переменной УtmpФ присваивается значение УnilФ, иначе казателю на следующий элемент (next) предыдущего элемента перед предыдущим до текущего элемента присваивается казатель на текущий элемент, локальной переменной (tmp) присваивается казатель на предыдущий элемент перед предыдущим до текущего элемента. После выяснения местоположения и выполнения некоторых команд, казателю на предыдущий элемент перед предыдущим до текущего элемента присваивается казатель на текущий элемент, казателю на следующий элемент предыдущего перед текущим элементом присваивается казатель на следующий после текущего; внутри текущего элемента казателю на следующий элемент присваивается казатель на предыдущий элемент, и казателю на предыдущий элемент присваивается локальная переменная УtmpФ. Если же текущий элемент окажется не меньше чем предыдущий перед ним элемент, тогда казателю на текущий элемент (temp) присваивается казатель на предыдущий перед ним элемент (prev). На этом выполнение вложенного цикла завершается.

Если во время поверки наличия элементов в списке окажется, что он пуст, то выводится сообщение: Таблица пуста.

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

Листинг программного изделия на языке программирования УPascalФ.

Program kursovik;

uses crt;

type Ukazat=^Inform;

Inform=record fam:string[15];

name:string[15];

fanem:string[15];

bethday:string[21];

zodiak:string[8];

next:Ukazat;

prev:Ukazat;

end;

ar temp,first,cut:Ukazat;

ch:char;

s1,s2:string;

n:integer;

m:boolean;

ffam,fname,ffanem:string[10];

Procedure Dobav;

begin

ClrScr;

new(temp);

write('Введите фамилию: ');

readln(temp^.fam);

write('Введите имя: ');

readln(temp^.name);

write('Введите отчество: ');

readln(temp^.fanem);

write('Введите дату рождения: ');

readln(temp^.bethday);

n:=1;

s2:=copy(temp^.bethday,n,1);

while ((s2<'0') or (s2>'9')) and (n<10) do

begin

inc(n);

s2:=copy(temp^.bethday,n,1);

end;

inc(n);

s1:=copy(temp^.bethday,n,1);

if (s1>='0') and (s1<='9') then s2:=s2+s1

else s2:='0'+s2;

while ((s1<'А') or (s1>'я')) and (n<10) do

begin

inc(n);

s1:=copy(temp^.bethday,n,1);

end;

s1:=copy(temp^.bethday,n,3);

temp^.zodiak:=' ';

if s1='апр' then

if s2<'21' then temp^.zodiak:='овен'

else temp^.zodiak:='телец';

if s1='мая' then

if s2<'21' then temp^.zodiak:='телец'

else temp^.zodiak:='близнецы';

if s1='июн' then

if s2<'22' then temp^.zodiak:='близнецы'

else temp^.zodiak:='рак';

if s1='июл' then

if s2<'23' then temp^.zodiak:='рак'

аelse temp^.zodiak:='лев';

if s1='авг' then

if s2<'24' then temp^.zodiak:='лев'

else temp^.zodiak:='дева';

if s1='сен' then

if s2<'24' then temp^.zodiak:='дева'

else temp^.zodiak:='весы';

if s1='окт' then

if s2<'24' then temp^.zodiak:='весы'

else temp^.zodiak:='скорпион';

if s1='ноя' then

if s2<'23' then temp^.zodiak:='скорпион'

else temp^.zodiak:='стрелец';

if s1='дек' then

if s2<'22' then temp^.zodiak:='стрелец'

else temp^.zodiak:='козерог';

if s1='янв' then

if s2<'21' then temp^.zodiak:='козерог'

else temp^.zodiak:='водолей';

if s1='фев'

then if s2<'21' then temp^.zodiak:='водолей'

else temp^.zodiak:='рыбы';

if s1='мар'

then if s2<'21' then temp^.zodiak:='рыбы'

else temp^.zodiak:='овен';

if first=nil then

аbegin

temp^.prev:=nil;

temp^.next:=nil;

first:=temp;

cut:=temp;

end

else begin

temp^.next:=nil;

temp^.prev:=cut;

cut^.next:=temp;

cut:=temp;

end;

end;{procedure}

Procedure Udal;

begin

ClrScr;

{1}if first=nil then

begin

writeln('Таблица пуста');

readln;

end

else

begin {else1}

write('Введите фамилию: ');

readln(ffam);

write('Введите имя: ');

readln(fname);

write('Введите отчество: ');

readln(ffanem);

temp:=first;

while ((ffam<>temp^.fam) or (fname<>temp^.name) or

(ffanem<>temp^.fanem)) and (temp<>nil) do

temp:=temp^.next;

{2}if temp=nil then

begin

write('Такого нет');

readln;

end

else

begin{else2}

{3}if first<>cut then

{4}if temp^.prev=nil then

begin

temp^.next^.prev:=temp^.prev;

first:=temp^.next;

end

else{4}

{5}if temp^.next=nil then

begin

temp^.prev^.next:=temp^.next;

cut:=temp^.prev;

end

else begin{else5}

temp^.prev^.next:=temp^.next;

temp^.next^.prev:=temp^.prev;

end{else5}

else {3} first:=nil;

dispose(temp);

end;{else2}

end;{else1}

end;{procedure}

Procedure Prosm;

begin

ClrScr;

temp:=first;

writeln('Фамилия Имя Отчество':27, 'Дата рождения':27,'Знак зодиака':20);

write('');

if first<>nil then

begin

while temp<>nil do

begin

n:=length(temp^.fam)+length(temp^.name)+length(temp^.fanem);

writeln(temp^.fam,' ',temp^.name,' ',temp^.fanem,

temp^.bethday:55-n,temp^.zodiak:15);

temp:=temp^.next;

end;

end

else writeln('Таблица пуста':40);

readln;

end;

Procedure Sortir;

ar

tmp:ukazat;

begin

ClrScr;

if first<>nil then

begin

m:=true;

{0}while m=trueа do

begin

m:=false;

temp:=first;

while temp^.next<>nil do

begin{1}

if (temp^.fam>temp^.next^.fam) or

(temp^.fam=temp^.next^.fam) and

(temp^.name>temp^.next^.name) or

(temp^.fam=temp^.next^.fam) and

(temp^.name=temp^.next^.name) and

(temp^.fanem=temp^.next^.fanem) then

begin{2}

m:=true;

if temp=first then

first:=temp^.next

else temp^.prev^.next:=temp^.next;

if temp^.next=cut then

begin

cut:=temp;

tmp:=nil;

end

else begin{3}

temp^.next^.next^.prev:=temp;

tmp:=temp^.next^.next;

end;{3}

temp^.next^.next:=temp;

temp^.next^.prev:=temp^.prev;

temp^.prev:=temp^.next;

temp^.next:=tmp;

end{2}

else temp:=temp^.next;

end;{1}

m:=false;

temp:=cut;

while temp^.prev<>nil do

begin{2.1}

if (temp^.fam<temp^.prev^.fam) or

(temp^.fam=temp^.prev^.fam) and

(temp^.name<temp^.prev^.name) or

(temp^.fam=temp^.prev^.fam) and

(temp^.name=temp^.prev^.name) and

(temp^.fanem<temp^.prev^.fanem) then

begin{2.2}

m:=true;

if temp=cut then cut:=temp^.prev

else temp^.next^.prev:=temp^.prev;

if temp^.prev=first then

begin

first:=temp;

tmp:=nil;

end

else

begin{2.3}

temp^.prev^.prev^.next:=temp;

tmp:=temp^.prev^.prev;

end;{2.3}

temp^.prev^.prev:=temp;

temp^.prev^.next:=temp^.next;

temp^.next:=temp^.prev;

temp^.prev:=tmp;

end{2.2}

else temp:=temp^.prev;

end;{2.1}

end;{0}

end

else begin

writeln('Таблица пуста');

readln;

end;

end;

begin

first:=nil;

repeat

ClrScr;

writeln('Выберите действие:');

writeln('1-Добавить');

writeln('2-Удалить');

writeln('3-Просмотреть');

writeln('4-Сортировать');

writeln('0-Выход');

readln(ch);

case ch of

'1':Dobav;

'2':Udal;

'3':Prosm;

'4':Sortir;

end;

until ch='0';

end.

Листинг программного изделия на языке программирования СФ.

#include<stdio.h>

#include<stdlib.h>

#include<conio.h>

#include<alloc.h>

typedef

struct inform

{char name[15],fam[15],fanem[15],b_day[3],b_manth[10],b_year[5],zodiak[8];

struct inform *next,*prev;};

struct inform *first,*cut,*temp;

int n,i;

char s1[10],s2[10];

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

void Dobav ( )

{

clrscr();

if ((temp=(struct inform*)malloc(sizeof(struct inform)))==NULL)exit(1);

printf("Введите фамилию: ");

scanf("%s",(*temp).fam);

printf("Введите имя: ");

scanf("%s",(*temp).name);

printf("Введите отчество: ");

scanf("%s",(*temp).fanem);

printf("Введите день рождения: ");

scanf("%s",(*temp).b_day);

printf("Введите месяц рождения: ");

scanf("%s",(*temp).b_manth);

printf("Введите год рождения: ");

scanf("%s",(*temp).b_year);

strcpy(s2,(*temp).b_day);

strncpy(s1,(*temp).b_manth,3);

strcpy((*temp).zodiak," ");

if (strcmp(s1,"апр")==0)

if (strcmp(s2,"21")<0) strcpy((*temp).zodiak,"овен");

else strcpy((*temp).zodiak,"телец");

if (strcmp(s1,"мая")==0)

if (strcmp(s2,"21")<0) strcpy((*temp).zodiak,"телец");

else strcpy((*temp).zodiak,"близнецы");

if (strcmp(s1,"июн")==0)

if (strcmp(s2,"22")<0) strcpy((*temp).zodiak,"близнецы");

else strcpy((*temp).zodiak,"рак");

if (strcmp(s1,"июл")==0)

if (strcmp(s2,"23")<0) strcpy((*temp).zodiak,"рак");

else strcpy((*temp).zodiak,"лев");

if (strcmp(s1,"авг")==0)

if (strcmp(s2,"24")<0) strcpy((*temp).zodiak,"лев");

else strcpy((*temp).zodiak,"дева");

if (strcmp(s1,"сен")==0)

if (strcmp(s2,"24")<0) strcpy((*temp).zodiak,"дева");

else strcpy((*temp).zodiak,"весы");

if (strcmp(s1,"окт")==0)

if (strcmp(s2,"24")<0) strcpy((*temp).zodiak,"весы");

else strcpy((*temp).zodiak,"скорпион");

if (strcmp(s1,"ноя")==0)

if (strcmp(s2,"23")<0) strcpy((*temp).zodiak,"скорпион");

else strcpy((*temp).zodiak,"стрелец");

if (strcmp(s1,"дек")==0)

if (strcmp(s2,"22")<0) strcpy((*temp).zodiak,"стрелец");

else strcpy((*temp).zodiak,"козерог");

if (strcmp(s1,"янв")==0)

if (strcmp(s2,"21")<0) strcpy((*temp).zodiak,"козерог");

else strcpy((*temp).zodiak,"водолей");

if (strcmp(s1,"фев")==0)

if (strcmp(s2,"21")<0) strcpy((*temp).zodiak,"водолей");

else strcpy((*temp).zodiak,"рыбы");

if (strcmp(s1,"мар")==0)

if (strcmp(s2,"21")<0) strcpy((*temp).zodiak,"рыбы");

else strcpy((*temp).zodiak,"овен");

if (first==NULL)

{

(*temp).next=NULL;

(*temp).prev=NULL;

аfirst=temp;

cut=temp;

}

else

{

(*temp).next=NULL;

(*temp).prev=cut;

(*cut).next=temp;

cut=temp;

}

}

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

oid Udal ( )

{

char ffam[10],fname[10],ffanem[10];

clrscr();

if (first==NULL) printf("Таблица пуста\n");

else

{

printf("Введите фамилию: ");

scanf("%s",ffam);

printf("Введите имя: ");

scanf("%s",fname);

printf("Введите отчество: ");

scanf("%s",ffanem);

temp=first;

while((strcmp(ffam, (*temp).fam) || strcmp(fname,(*temp).name) ||

strcmp(ffanem,(*temp).fanem)) && temp!=NULL)

temp=(*temp).next;

if (temp==NULL) printf("Нет такого");

else

{

if (first!=cut)

if ((*temp).prev==NULL)

{

а(*(*temp).next).prev=(*temp).prev;

first=(*temp).prev;

}

else

if ((*temp).next==NULL)

{

(*(*temp).prev).next=(*temp).next;

cut=(*temp).prev;

}

else

{

(*(*temp).prev).next=(*temp).next;

(*(*temp).next).prev=(*temp).prev;

}

else first=NULL;

free(temp);

}

}

scanf("%s");

}

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

oid Prosm ( )

{

clrscr();

if (first==NULL) printf("Таблица пуста");

else

{

printf("Фамилия Имя Отчество Дата рождения");

printf(" Знак зодиака");

printf("\n--------------------------------------------------------------------------------");

temp=first;

do

{

n=strlen((*temp).fam)+strlen((*temp).name)+strlen((*temp).fanem);

printf("\n%s %s %s ",(*temp).fam,(*temp).name,(*temp).fanem);

i=1;

while (i<39-n)

{

printf(" ");

i++;

}

printf("%s ",(*temp).b_day);

printf("%s ",(*temp).b_manth);

printf("%s ",(*temp).b_year);

n=n+i+strlen((*temp).b_day)+strlen((*temp).b_manth)+strlen((*temp).b_year);

i=1;

while (i<61-n)

{

printf(" ");

i++;

}

printf("%s",(*temp).zodiak);

temp=(*temp).next;

}

while (temp!=NULL);

}

scanf("%s");

}

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

oid Sortir ( )

{

struct inform *tmp;

int m;

clrscr();

if (first!=NULL)

{

m=1;

while(m==1)

{

m=0;

temp=first;

while((*temp).next!=NULL)

{

if((strcmp((*temp).fam,(*(*temp).next).fam)>0) ||

(strcmp((*temp).fam,(*(*temp).next).fam)==0) &&

(strcmp((*temp).name,(*(*temp).next).name)>0) ||а

(strcmp((*temp).fam,(*(*temp).next).fam)==0) &&

(strcmp((*temp).name,(*(*temp).next).name)==0) &&а

(strcmp((*temp).fanem,(*(*temp).next).fanem)>0))

{

m=1;

if (temp==first) first=(*temp).next;

else (*(*temp).prev).next=(*temp).next;

if ((*temp).next==cut)

{

cut=temp;

tmp=NULL;

}

else

{

(*(*(*temp).next).next).prev=temp;

tmp=(*(*temp).next).next;

}

(*(*temp).next).next=temp;

(*(*temp).next).prev=(*temp).prev;

(*temp).prev=(*temp).next;

(*temp).next=tmp;

}

else temp=(*temp).next;

}

m=0;

temp=cut;

while((*temp).prev!=NULL)

{

if((strcmp((*temp).fam,(*(*temp).prev).fam)<0) ||

(strcmp((*temp).fam,(*(*temp).prev).fam)==0) &&

(strcmp((*temp).name,(*(*temp).prev).name)<0) ||

(strcmp((*temp).fam,(*(*temp).prev).fam)==0) &&

(strcmp((*temp).name,(*(*temp).prev).name)==0) &&

(strcmp((*temp).fanem,(*(*temp).prev).fanem)<0))

{

m=1;

if (temp==cut) cut=(*temp).prev;

else (*(*temp).next).prev=(*temp).prev;

if ((*temp).prev==first)

{

first=temp;

tmp=NULL;

}

else

{

(*(*(*temp).prev).prev).next=temp;

tmp=(*(*temp).prev).prev;

}

(*(*temp).prev).prev=temp;

(*(*temp).prev).next=(*temp).next;

(*temp).next=(*temp).prev;

(*temp).prev=tmp;

}

else temp=(*temp).prev;

}

}

}

else printf("Таблица пуста");

scanf("%s");

}

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

oid main()

{

char ch;

first=NULL;

do

{

clrscr();

printf("Выберте действие\n1-Добавить\n2-Удалить\n");

printf("3-Просмотреть\n4-Сортировать\n0-Выход");

scanf("%d",&ch);

switch(ch)

{

case 1:Dobav();break;

case 2:Udal();break;

case 3:Prosm();break;

case 4:Sortir();break;

}

}

while(ch);

}