Консультация № 175639
26.12.2009, 22:31
0.00 руб.
27.12.2009, 05:56
0 9 0
Уважаемые эксперты, помогите пожалуйста с кодом, это линейный двусвязный список, по строке адрес, при добавлении, элементы должны выстраиватся по алфавиту. Тоесть мы сравнием новый элемент с текущим, и если надо делаем его первым( например там Б, мы добавляем А, и А становится первым), или последним. А как сделать чтобы оно добаляло в середину(например между А и В)? Помогите пожалуйста. Вот блок схема и приложение, чтобы было легче разобраться:


Приложение:
type
tp=^el;
el=record
adres:string[30];
Komnat:byte;
Chel:byte;
Ploshad:word;
ZhilPloshad:word;
next:tp;//следующий
prev:tp;//предыдущий
end;
public
{ Public declarations }
first, last:tp; // first - первый эл-нт, last - последний
end;
procedure TForm1.BitBtn1Click(Sender: TObject); //добавление элемента
var z:boolean;
p,d:tp;
begin
z:=false;
while z=false do// пока z=false мы заносим значения, когда z=true это значит что
//значение занесено и тогда end и вывод в CmbBox-ы '' пустые значение, для
//повторного занесение данных и добавления нового эл-та
begin
if n=nil then //не пуст ли список, если пуст, то
begin
new(n); //создаем новый эл-нт
n^.adres:=ComboBox2.Text; //заносим данные:
n^.Komnat:=strtoint(ComboBox3.Text);
n^.Chel:=strtoint(ComboBox4.Text);
n^.Ploshad:=strtoint(ComboBox5.Text);
n^.ZhilPloshad:=strtoint(ComboBox6.Text);
first:=n;//если список пуст, то новый эл-нт является первым
last:=n; //и последним, поэтому обозначаем это указателями
n^.prev:=nil;//не забываем "занулять" указатели
n^.next:=nil;//аналогично
z:=true;
end
else
begin
p:=first;
while (p^.next<>Nil) do
p:=p^.next;
if p^.adres>ComboBox2.Text then
begin
new(p); //создаем новый эл-нт
p^.adres:=Form1.ComboBox2.Text; //заносим данные:
p^.Komnat:=strtoint(Form1.ComboBox3.Text);
p^.Chel:=strtoint(Form1.ComboBox4.Text);
p^.Ploshad:=strtoint(Form1.ComboBox5.Text);
p^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
first^.prev:=p; //доббавляем эл-нт перед первым и делаем его первым
p^.next:=first;
first:=p;
p^.prev:=nil;//перед первым эл-том Nil
z:=true;
end
else
begin
new(d); //создаем новый эл-нт
d^.adres:=Form1.ComboBox2.Text; //заносим данные:
d^.Komnat:=strtoint(Form1.ComboBox3.Text);
d^.Chel:=strtoint(Form1.ComboBox4.Text);
d^.Ploshad:=strtoint(Form1.ComboBox5.Text);
d^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
last^.next:=d;//добавляем новый эл-нт после следующего
d^.prev:=last;
last:=d;
d^.next:=nil;//"зануляем" указатель, обозначаем что следующий после последнего Nil
z:=true;
end;
end;
end;
end;
ComboBox2.Text:='';
ComboBox3.Text:='';
ComboBox4.Text:='';
ComboBox5.Text:='';
ComboBox6.Text:='';
end;

Обсуждение

Неизвестный
27.12.2009, 03:58
общий
Извините, пожалуйста, блок схему рисовал в три часа ночи и все напутал, вот исправленный вариант, помогите разобраться вставить элемент в середину между двумя.
давно
Профессионал
304622
583
30.12.2009, 13:52
общий
Камынин Владислав Дмитриевич:
Данный код тоже обрывочный. Кое о чём я догадался. Например, что
ComboBox2.Text:='';
ComboBox3.Text:='';
ComboBox4.Text:='';
ComboBox5.Text:='';
ComboBox6.Text:='';
должны быть в обработчике FormActivate. Я добавил необхоимое для компиляции, и привыполнении получил ошибку обращения к памяти, т.е. что-то неправильно в работе со списком. Есть работающий текст?
Неизвестный
31.12.2009, 00:25
общий
Сергей Бендер, мне уже практически удалось упорядочить список. Единственное, только в одном случае происходит ошибка. Упорядочивание происходит при добавлении элемента в список, методом вставки. То есть мы сравниваем ключи, и ищем место, куда добавить новый элемент. Ключом является - "адрес". Если можете, помогите, пожалуйста. Я уже все сделал, остался только этот маленький кусочек. Случай, при котором происходит ошибка, выделен в коде (когда я пытаюсь добавить элемент после первого), если что не понятно спрашивайте я все детально объясню:
Код:
type
tp=^el;
el=record
adres:string[30];
Komnat:byte;
Chel:byte;
Ploshad:word;
ZhilPloshad:word;
next:tp;//следующий
prev:tp;//предыдущий
end;
public
{ Public declarations }
first, last:tp;
end;

var
n:tp;
first, last:tp;
Form1: TForm1;

procedure TForm1.Dobavit(z:boolean); //добавление элемента
var p:tp;
begin
z:=false;
while z=false do// пока z=false мы заносим значения, когда z=true это значит что
//значение занесено и тогда end и вывод в CmbBox-ы '' пустые значение, для
//повторного занесение данных и добавления нового эл-та
begin
if n=nil then //не пуст ли список, если пуст, то
begin
new(n); //создаем новый эл-нт
n^.adres:=ComboBox2.Text; //заносим данные:
n^.Komnat:=strtoint(ComboBox3.Text);
n^.Chel:=strtoint(ComboBox4.Text);
n^.Ploshad:=strtoint(ComboBox5.Text);
n^.ZhilPloshad:=strtoint(ComboBox6.Text);
first:=n;//если список пуст, то новый эл-нт является первым
last:=n; //и последним, поэтому обозначаем это указателями
n^.prev:=nil;//не забываем "занулять" указатели
n^.next:=nil;//аналогично
z:=true;
end
else
begin
while (n^.next<>Nil) and (n^.next^.adres<ComboBox2.Text) do
n:=n^.next;
if (n=first) and (n^.adres>ComboBox2.Text) then
begin
new(p); //создаем новый эл-нт
p^.adres:=Form1.ComboBox2.Text; //заносим данные:
p^.Komnat:=strtoint(Form1.ComboBox3.Text);
p^.Chel:=strtoint(Form1.ComboBox4.Text);
p^.Ploshad:=strtoint(Form1.ComboBox5.Text);
p^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
first^.prev:=p; //добавляем эл-нт перед первым и делаем его первым
p^.next:=first;
first:=p;
p^.prev:=nil;//перед первым эл-том Nil
z:=true;
end
else
begin
if (n=first) and (n^.adres<ComboBox2.Text)then
begin
new(p); //создаем новый эл-нт
p^.adres:=Form1.ComboBox2.Text; //заносим данные:
p^.Komnat:=strtoint(Form1.ComboBox3.Text);
p^.Chel:=strtoint(Form1.ComboBox4.Text);
p^.Ploshad:=strtoint(Form1.ComboBox5.Text);
p^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
p^.next:=first^.next;
p^.prev:=first;
first^.next:=p;
p^.next^.prev:=n;
z:=true;
end

else
begin
if (n=last) and (n^.adres<ComboBox2.Text) then
begin
new(p); //создаем новый эл-нт
p^.adres:=Form1.ComboBox2.Text; //заносим данные:
p^.Komnat:=strtoint(Form1.ComboBox3.Text);
p^.Chel:=strtoint(Form1.ComboBox4.Text);
p^.Ploshad:=strtoint(Form1.ComboBox5.Text);
p^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
last^.next:=p;//добавляем новый эл-нт после следующего
p^.prev:=last;
last:=p;
p^.next:=nil;//"зануляем" указатель, обозначаем что следующий после последнего Nil
z:=true;
end
else
begin
if n^.next<>Nil then //добавляем в середину
begin
new(p); //создаем новый эл-нт
p^.adres:=Form1.ComboBox2.Text; //заносим данные:
p^.Komnat:=strtoint(Form1.ComboBox3.Text);
p^.Chel:=strtoint(Form1.ComboBox4.Text);
p^.Ploshad:=strtoint(Form1.ComboBox5.Text);
p^.ZhilPloshad:=strtoint(Form1.ComboBox6.Text);
p^.prev:=n;
p^.next:=n^.next;
p^.next^.prev:=p;
n^.next:=p;
z:=true;
end;
end;
end;
end;
end;
end;
ComboBox2.Text:='';
ComboBox3.Text:='';
ComboBox4.Text:='';
ComboBox5.Text:='';
ComboBox6.Text:='';
end;
procedure TForm1.BitBtn1Click(Sender: TObject); //вызов процедуры добавления, и сразу просмотр
var b:boolean;
i:integer;
l:tp;
begin
b:=true;
if ComboBox2.Text='' then
begin
b:=false;
MessageDlg('Не правильно введено поле адрес квартиры!', mtError, [mbOk], 0);
end
else
if ComboBox3.Text='' then
begin
b:=false;
MessageDlg('Не правильно введено поле кол-во комнат!', mtError, [mbOk], 0);
end
else
if ComboBox4.Text='' then
begin
b:=false;
MessageDlg('Не правильно введено поле кол-во жильцов!', mtError, [mbOk], 0);
end
else
if ComboBox5.Text='' then
begin
b:=false;
MessageDlg('Не правильно введено поле общая площадь!', mtError, [mbOk], 0);
end
else
if ComboBox6.Text='' then
begin
b:=false;
MessageDlg('Не правильно введено поле жилая площадь!', mtError, [mbOk], 0);
end;


if b=true then
begin
Dobavit(true);
StrGrd.Visible:=true;
StrGrd.RowCount:=1;
i:=1;
l:=n;
l:=first;
if n=Nil then
MessageDlg('Список пуст!', mtError, [mbOk], 0);
while l<>nil do
begin
StrGrd.RowCount:=StrGrd.RowCount+1;
StrGrd.FixedRows:=1;
StrGrd.Cells[0,i]:=inttostr(i);
StrGrd.Cells[1,i]:=l^.adres;
StrGrd.Cells[2,i]:=inttostr(l^.Komnat);
StrGrd.Cells[3,i]:=inttostr(l^.Chel);
StrGrd.Cells[4,i]:=inttostr(l^.Ploshad);
StrGrd.Cells[5,i]:=inttostr(l^.ZhilPloshad);
l:=l^.next;
i:=i+1;
end;
end;
end;


давно
Профессионал
304622
583
05.01.2010, 09:47
общий
Камынин Владислав Дмитриевич:
Извини, у меня компьютер сбоит -- тот, на котором Дельфа может работать. Как смогу, попробую разобраться.
Неизвестный
05.01.2010, 21:49
общий
Камынин Владислав Дмитриевич:
Добрый вечер! Актуален ли еще вопрос? По-моему, у Вас уже в блок-схеме некорректность. В любом случае создается новый элемент, затем ищется для него место вставки. Если Вы пишете одновременно одно значение в список - должен быть один цикл (пока не закончится список) и (не найдено место вставки).
Неизвестный
06.01.2010, 02:52
общий
Сергей Бендер, Lamed, спасибо что откликнулись! Задание я уже решил . Я все понял! Урааа!
должен быть один цикл (пока не закончится список) и (не найдено место вставки)

Да, вы правы. Я так и сделал. Спасибо
у Вас уже в блок-схеме некорректность

Да, вы правы. Просто современный народ, сначала пишет программы, а потом к ним рисует блок-схемы
Неизвестный
06.01.2010, 03:03
общий
Вот мой алгоритм. Правильно?
Неизвестный
06.01.2010, 09:04
общий
Камынин Владислав Дмитриевич:
По-моему, нормально, хотя, конечно, надо для ясности сопоставить с последней версией Вашего кода.
давно
Профессионал
304622
583
06.01.2010, 14:32
общий
Камынин Владислав Дмитриевич:
Цитата: 273093
Просто современный народ, сначала пишет программы, а потом к ним рисует блок-схемы


В жизни ни одной блок-схемы для _своих_ программ не нарисовал.
Форма ответа