当我编译我的代码是好的,但是当我调用并执行函数Quicksort时,程序似乎处于无限循环中。我能做什么 ? 我测试了所有函数,但似乎问题出在tQuicksort函数中。 我是初学者。
let h l =
match l with
| [] -> raise (Failure "head")
| x::xs -> x;;
let t l =
match l with
| [] -> raise (Failure "tail")
| x::xs -> xs;;
let rec trev l r =
match l with
| [] -> r
| x::xs -> trev xs (x::r);;
let rev l = trev l [];;
let rec tunir l1 l2 r =
match l1 with
| [] -> if l2 == [] then
rev r
else
tunir [] (t l2) ((h l2)::r)
| x1::xs1 -> tunir xs1 l2 (x1::r);;
let unir l1 l2 = tunir l1 l2 [];;
let rec tpart x l l1 l2 =
match l with
| [] -> if l1 == [] then
((x::[]), l2)
else
(l1, (x::l2))
| (lx:: lxs) -> if (h l) <= x then
tpart x (t l) ((h l)::l1) l2
else
tpart x (t l) l1 ((h l)::l2);;
let part x l = tpart x l [] [];;
let rec tnroelem l n =
match l with
| [] -> n
| x::xs -> tnroelem (t l) (n+1);;
let nroelem l = tnroelem l 0;;
let rec tunirL l r =
match l with
| [] -> rev r
| lx::lxs -> if lx == [] then tunirL lxs r
else tunirL((t lx)::lxs) ((h lx)::r);;
let unirL l = tunirL l [];;
let rec tquicksort lm l lM =
match l with
| [] -> unirL (unir (rev lm) lM)
| lx::lxs -> let (la, lb) = part (h l) (t l) in
if (nroelem la < nroelem lb) then tquicksort ((quicksort la)::lm) lb lM
else tquicksort lm la ((quicksort lb)::lM)
and quicksort l = tquicksort [] l [];;
let rec geraListaT n l =
if n == 0 then l
else geraListaT (n-1) (n::l);;
let geraLista n = geraListaT n [];;
let lista : int list = geraLista 9;;
List.iter (fun x->print_int x) (quicksort lista)
答案 0 :(得分:4)
当您尝试quicksort lm l lM
并且l
只有一个元素时,您错过了一个案例。在这种情况下,所采取的分支是
| lx::lxs -> let (la, lb) = part (h l) (t l) in
if (nroelem la < nroelem lb)
then tquicksort ((quicksort la)::lm) lb lM
else tquicksort lm la ((quicksort lb)::lM)
然后,无论if
的结果如何,您都会执行递归调用quicksort lm' l' lM'
,其中l'
也只有一个元素。这可以通过在空列表之后添加一个额外的案例来修复:
| lx::[] -> unirL (unir (rev (l :: lm)) lM)