IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Сортировка списка слиянием.
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 1
Пол: Мужской

Репутация: -  0  +


Добрый вечер, уважаемые форумчане!
Посмотрите мой код, пожалуйста!

Задача была написать сортировку слиянием для списка.
Проблема в программе: она заканчивает работу с ошибкой 216, я не могу понять почему... Так же, если посмотреть на вывод списка, он постепенно уменьшается. Куда пропадают элементы?sad.gif
Что не так? Помогите, пожалуйста, найти ошибку!


Program mergelist;
uses
crt;
type
Tinf=integer;
List=^TList;
TList=record
data:TInf;
next:List;
end;

var i, l:integer;
f:text;
path:string;
dff: integer;
counter, moveCounter, n, k, i1: integer;
spis, tmp1, lastelem:List;
ch:char;

{Список}
{Процедура добавления нового элемента в односвязный список}
procedure AddElem(var spis1:List;znach1:TInf);
var
tmp:List;
begin
if spis1=nil then
begin
GetMem(spis1,sizeof(TList));
tmp:=spis1;
end
else
begin
tmp:=spis1;
while tmp^.next<>nil do
tmp:=tmp^.next;
GetMem(tmp^.next,sizeof(TList));
tmp:=tmp^.next;
end;
tmp^.next:=nil;
tmp^.data:=znach1;
end;

{процедура печати списка}
procedure Print(spis1:List);
begin
if spis1=nil then
begin
writeln('Список пуст.');
exit;
end;
while spis1<>nil do
begin
Write(spis1^.data, ' ');
spis1:=spis1^.next
end;
end;


{Сортировка}

{Процедура слияния}
function merge(priorNode1, priorNode2: list; count1, count2: integer): list;

var i:integer;
node1, node2, lastnode, temp: list;

begin
writeln('begin merge');
lastnode:=priornode1;
node1:=priornode1^.next;
node2:=priornode2^.next;

while (count1<>0) and (count2<>0) do begin
if (node1^.data <= node2^.data) then begin
lastnode:=node1;
node1:=node1^.next;
dec(count1);
end

else begin
temp:=node2^.next;
node2^.next:=node1;
lastnode^.next:=node2;
lastnode:=node2;
node2:=temp;
dec(count2);
end;
end;

if (count1 = 0) then begin
lastnode^.next:=node2;
for i:=0 to pred(count2) do
lastnode:=lastnode^.next;
end

else begin
for i:=0 to pred(count2) do
lastnode:=lastnode^.next;
lastnode^.next:=node2;
end;

merge:=lastnode;
end;

{рекурсивная сортировка}
function mergesort(priorNode: list; count: integer): list;
var
count2:integer;
priorNode2:list;
dummyNode:list;

begin
if (count=1) then begin
writeln('begin 1 mergesort');
mergesort:=priorNode^.next;
exit;
end;
count2:=count div 2;
count:=count-count2;
writeln('count ', count);
writeln('count2 ', count2);
priorNode2:=mergesort(priorNode, count);
dummyNode:=mergesort(priorNode2, count2);

mergesort:=merge (priorNode, priorNode2, count, count2);
writeln('spis');
print(spis);

end;

{запускаем сортировку}
procedure sort (fhead: list; count:integer);
begin
if (count>1) then mergesort (fHead, count);

{issorted:=true;}
end;


{программа}
begin
Spis:=nil;

clrscr;
For i1:=1 to 1 do begin
counter:=0; {счетчик сравнений}
moveCounter:=0; {счетчик перемещений}
Spis:=nil;
tmp1:=nil;

case i1 of
1: begin path:='input.txt'; n:=10 end;

end;

assign(f,path);
reset(f);

{читаем содержимое файла, записываем его в список}
while not eof(f) do begin
readln(f, dff);
AddElem(spis, dff);
end;
end;

print(spis);
writeln('--end of list--');

sort(spis, n);
print(spis);


end.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Знаток
****

Группа: Пользователи
Сообщений: 481
Пол: Мужской
Реальное имя: Федосеев Павел

Репутация: -  9  +


Чтобы легче было читать и разбираться с текстом программы - советую воспользоваться форматтером кода JCF.

Далее. Как говорят в голливудских фильмах: "Ты работаешь со списком и должен думать как список".
Это я к тому, что у списка нет индексов. И сортировку можно организовать примерно так

procedure Sort(var a: List);
var
left,
right,
tmp: List;
n: integer;
begin
{подсчёт числа элементов}
tmp:= a;
while tmp<>nil do
begin
inc(n);
tmp:=tmp^.next;
end;
if n>1 then
begin
{делим список на две части}
........................................
{вызываем рекурсивный метод для каждой}
Sort(left);
Sort(right);

{сливаем два списка в один}
......................................
end;
end;


Причём, т.к. работаем со списком, то при разделении списка на две части, делаем так, чтобы оба списка left и right были независимы - т.е. последний элемент списков left и right должен указывать на nil.

Сообщение отредактировано: Федосеев Павел -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Знаток
****

Группа: Пользователи
Сообщений: 481
Пол: Мужской
Реальное имя: Федосеев Павел

Репутация: -  9  +


Примерно, так
program mergelist;

uses
crt;

type
Tinf = integer;
List = ^TList;

TList = record
Data: TInf;
Next: List;
end;

{Список}
{Процедура добавления нового элемента в односвязный список}
procedure AddElem(var spis1: List; znach1: TInf);
var
tmp: List;
begin
if spis1 = nil then
begin
GetMem(spis1, sizeof(TList));
tmp := spis1;
end
else
begin
tmp := spis1;
while tmp^.Next <> nil do
tmp := tmp^.Next;
GetMem(tmp^.Next, sizeof(TList));
tmp := tmp^.Next;
end;
tmp^.Next := nil;
tmp^.Data := znach1;
end;

{процедура печати списка}
procedure Print(spis1: List);
begin
if spis1 = nil then
begin
WriteLn('Список пуст.');
exit;
end;
while spis1 <> nil do
begin
Write(spis1^.Data, ' ');
spis1 := spis1^.Next;
end;
end;

{процедура освобождения памяти списка}
procedure FreeList(var spis: List);
var
tmp: List;
begin
while spis <> nil do
begin
tmp := spis;
spis := spis^.Next;
FreeMem(tmp, sizeof(TList));
end;
end;

{Сортировка}
procedure MergeSort(var a: List);
var
left, right, tmp, LastInA: List;
i, n: integer;
begin
{подсчёт числа элементов}
n := 0;
tmp := a;
while tmp <> nil do
begin
Inc(n);
tmp := tmp^.Next;
end;

if n > 1 then
begin
{делим список на две части}
left := a;
tmp := a;
for i := 1 to (n div 2) - 1 do
tmp := tmp^.Next;
right := tmp^.Next;
tmp^.Next := nil;
a := nil; {т.к. единого списка a уже не существует}
Print(left);
Write(' --- ');
Print(right);
WriteLn;
{вызываем рекурсивный метод для каждой}
MergeSort(left);
MergeSort(right);
{сливаем два списка в один}
LastInA := nil;
tmp := nil;
while (left <> nil) and (right <> nil) do
begin
if left^.Data > right^.Data then
begin
tmp := left;
left := left^.Next;
end
else
begin
tmp := right;
right := right^.Next;
end;
tmp^.Next := nil;
if a = nil then
begin
a := tmp;
LastInA := a;
end
else
begin
LastInA^.Next := tmp;
LastInA := LastInA^.Next;
end;
end;
if left <> nil then
LastInA^.Next := left;
if right <> nil then
LastInA^.Next := right;
end;
end;

var
f: Text;
path: string;
dff: integer;
counter, moveCounter: integer;
spis: List;

{программа}
begin
clrscr;
counter := 0; {счетчик сравнений}
moveCounter := 0; {счетчик перемещений}

{читаем содержимое файла, записываем его в список}
path := 'input.txt';
Assign(f, path);
reset(f);
Spis := nil;
while not EOF(f) do
begin
readln(f, dff);
AddElem(spis, dff);
end;

WriteLn('Incoming list:');
Print(spis);
WriteLn('--end of list--');

MergeSort(spis);

WriteLn('Sorted list:');
Print(spis);
WriteLn('--end of list--');

FreeList(spis);
end.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 27.05.2024 22:07
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name