Вопрос № 183227: Здравствуйте. Пожалуйста, помогите с этой задачей. В динамике совсем ничего не понимаю, а времени почти не осталось до зачета. Создать в динамической памяти односвязный кольцевой список из 2n элементов (число n >= 1, задается пользователем)...
Вопрос № 183227:
Здравствуйте. Пожалуйста, помогите с этой задачей. В динамике совсем ничего не понимаю, а времени почти не осталось до зачета.
Создать в динамической памяти односвязный кольцевой список из 2n элементов (число n >= 1, задается пользователем). Заполнение информационных полей элементов списка можно провести генератором случайных чисел в диапозоне [0..100]. Реализовать процедуры добавление элементов в любую точку списка, удаление любого члена из списка, вывод на экран полученной в куче числовой последовательности.
Из полученной динамической числовой пос-ти X1, X2, ...X2n вычислить: s={X1+Xn+1,X2+Xn+2,...,Xn+X2n}. Запрещается использовать массивы. Turbo Pascal либо PascalAbc.
Отвечает Сергей Бендер (Практикант) :
Здравствуйте, Посетитель - 373825!
Собственно, вот: (TurboPascal)
Код :
const nmax=100;
type pnode = ^node; {Элемент списка}
node = record
x:integer; {Значение элемента}
n:pnode; {Ссылка на следующий элемент}
end;
{Добавление элемента}
procedure vstavka(var p:pnode;a:integer);
var pp:pnode;
begin
{Если список пуст}
if p=nil
then begin
new(p); {Создаём элемент в переданной переменной}
p^.x:=a; {Заносим значение}
p^.n:=p; {Замыкаем на себя (минимальное кольцо)}
end
else begin
new(pp); {Создаём элемент во вспомогательной переменной}
pp^.x:=a; {Заносим значение}
pp^.n:=p^.n; {Вставляем в список}
p^.n:=pp;
end;
end;
{Удаление элемента}
procedure udal(var p:pnode;a:integer);
var pp:pnode;
begin
{Если список непуст}
if p<> nil
then begin
pp:=p; {Заносим начало списка во вспомогательную переменную }
repeat
{Проверяем значение _следуюущего_ за pp элемента.
т.к. корректное удаление можно сделать только для следующего элемента}
if pp^.n^.x = a
then begin
{Начинаем удалять}
p:=pp^.n;
{Текущий элемент замыкаем на послеследующий}
pp^.n:=pp^.n^.n;
dispose(p);
{Ставим указатель на список на следующий после
удалённого элемент. Это на тот случай,если
удалён сам p. В результате меняется порядок
вывода значений. Но поскольку задано было
создать колцо, Я счёл это допустимым.}
}
p:=pp^.n;
break; {Выход из цикла}
end;
pp:=pp^.n; {Перход на следующий элемент списка}
until p=pp; {Продолжается, пока не вернётся на начало}
end;
end;
{Вывод списка на экран}
procedure print(p:pnode);
var pp:pnode;
begin
{Если список непуст}
if p<>nil
then begin
write(p^.x:2,' '); {Выводим первый элемент - в кольце это надо делать особо}
pp:=p^.n;
{пробегаем по списку}
while pp<>p do
begin
write(pp^.x:2,' ');
pp:=pp^.n;
end;
end;
end;
{Поиск минимальной суммы Xi+Xi+n}
function minsum(p:pnode;n:integer):integer;
var i:integer;
pp:pnode;
s:integer;
begin
pp:=p;
{n раз сдвигаем вспомогательный указатель на элемент}
for i:=1 to n do
pp:=pp^.n;
s:=201; {Задаём заведомо большое значение}
for i:=1 to n do
begin
{Проверяем сумму}
if p^.x+pp^.x<s
then s:=p^.x+pp^.x;
p:=p^.n; {Сдвигаем элементы}
pp:=pp^.n;
end;
minsum:=s;
end;
{Удаление списка}
procedure sbros(var p:pnode);
var pp:pnode;
begin
{Если список непуст}
if p<>nil
then begin
{Пока элемент p не стал указывать сам на себя,
т.е. пока он не остался последним}
while p^.n<>p do
begin
{Удаляем соседние}
pp:=p^.n;
p^.n:=p^.n^.n;
dispose(pp);
end;
{Удаляем его самого}
dispose(p);
p:=nil;
end;
end;
var ring:pnode;
i:integer;
n,a:integer;
begin
ring:=nil;
randomize;
write('Vvedite n:');
readln(n);
for i:=1 to 2*n do
vstavka(ring,random(101));
print(ring);
writeln;
writeln('Min summa Xi+Xi+n = ',minsum(ring,n));
readln;
write('Kakoe chislo nado udalit? ');
readln(a);
udal(ring,a);
print(ring);
writeln;
readln;
sbros(ring);
readln;
end.
Испрален комментарий по просьбе автора ответа
-----
∙ Отредактировал: Зенченко Константин Николаевич (Модератор)
∙ Дата редактирования: 25.05.2011, 12:03 (время московское)
Ответ отправил: Сергей Бендер (Практикант)
Ответ отправлен: 25.05.2011, 02:51
Номер ответа: 267349 Тел.: 8-912-761-0437 Организация: Удмуртский ГосУнивеситет. г. Ижевск. Абонент Skype: ostapbskype
Оценка ответа: 5 Комментарий к оценке: Спасибо большое. Благодаря комментариям разобралась немного, как оно все работает.
Вам помог ответ? Пожалуйста, поблагодарите эксперта за это! Как сказать этому эксперту "спасибо"?
Отправить SMS#thank 267349
на номер 1151 (Россия) |
Еще номера »
Оценить выпуск »
Нам очень важно Ваше мнение об этом выпуске рассылки!
* Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи.
(полный список тарифов)
** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
*** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.