Você está na página 1de 14

Sorting algorithms

1. Insertion sort
Insertion sort is a simple sorting algorithm that is relatively efcient for small
lists and mostly sorted lists, and often is used as part of more sophisticated
algorithms. It works by taking elements from the list one by one and inserting
them in their correct position into a new sorted list. In arrays, the new list and
the remaining elements can share the array's space, but insertion is expensive,
reuiring shifting all following elements over by one. Shell sort is a variant of
insertion sort that is more efcient for larger lists.
!haracteristic
consist of " # 1 passes . $or pass p % 1 through " # 1, insertion sort
ensures that the elements in positions & through p are in sorted order.
Insertion sort makes use of the fact that elements in positions & through
p # 1 are already known to be in sorted order.
public class LinkedList {
public static void sort(Dlist L){
if (l.Size()<=1)return ;
DNode pivot;
DNode inst;
DNode end = L.et!irst();
"#ile (end$=L.etLast()){
pivot =end.etNe%t();
L.re&ove(pivot);
ins=end;
"#ile (L.#as'rev(ins)(( ins.et)le&ent().co&pare *o(pivot.et)le&ent())+,)
ins=ins.et'rev();
L.add-fter(ins.pivot);
if (ins==end);
end = end.etNe%t();
'
'
(.S)*)!+I," S,-+
Selection sort is an in.place comparison sort. It has ,/n
(
0 complexity, making it
inefcient on large lists, and generally performs worse than the similar
insertion sort. Selection sort is noted for its simplicity, and also has
performance advantages over more complicated algorithms in certain
situations. +he algorithm 1nds the minimum value, swaps it with the value in
the 1rst position, and repeats these steps for the remainder of the list. It does
no more than n swaps, and thus is useful where swapping is very expensive.
In summary selection sort works by
1nd minimum element in the list ,swap it with the beginning element and
repeat the above steps after moving pointer to next element
Steps of selection sort
1. +he list is divided into two sublists, sorted and unsorted, which are
divided by an imaginary wall.
1. 2e 1nd the smallest element from the unsorted sublist and swap it with
the element at the beginning of the unsorted data.
(. 3fter each selection and swapping, the imaginary wall between the two
sublists move one element ahead, increasing the number of sorted
elements and decreasing the number of unsorted ones.
3. )ach time we move one element from the unsorted sublist to the sorted
sublist, we say that we have completed a sort pass.
4. 3 list of n elements reuires n.1 passes to completely rearrange the data.
Implementation 5 Singly *inked *ist
"ode 6selectionsort/"ode 6list0
7
"ode 6tmp%list, 6tmp(, 6prev, 6i*st, 68*st9
"ode 6min9
if /:list0
7
..e&pt/ list no need sort
return list9
'
..s"appin t#e nodes "e re0uire previous node
prev % list9
for /i*st%list9 i*st ;; i*st.<next9 i*st%i*st.<next0
7
min % i*st9
for /8*st % i*st.<next9 8*st9 8*st % 8*st.<next0
7
..et t#e &ini&u& node
if /8*st.<info = min.<info0
7
..&ark t#e &ini&u& node "e #ad encountered so far
min % 8*st9
'
'
..s"ap t#e nodes if re0uired
if /i*st :% min0
7
tmp % min.<next9
..o 1nd &in2s previous node (&in node can be &an/ nodes a"a/ fro&
base node to be s"apped)
for /tmp(%i*st9tmp(.<next9 tmp(%tmp(.<next0
7
if /tmp(.<next %% min0
7
break9
'
'
..c#eck "#et#er node to s"apped is in beinin (i.e. #eader node)
if /prev :% i*st0
7
prev.<next % min9
'
else
7
..as "e do not #ave special #eader node3 if t#e 1rst node and so&e
..ot#er node3 need to be s"apped3 t#en update t#e list (&akes ne" &in
node as
..loical #eader)
list % min9
'
..are nodes to be s"apped nei#borin nodes4
if /i*st.<next %% min0
7
..nodes to be s"apped are nei#borin nodes3
..t#en s"ap t#e& si&pl/
min.<next % i*st9
i*st.<next % tmp9
'
else
7
..nodes to be s"apped are not nei#bor nodes3 t#e/ are apart
..so3 consider all scenarios
min.<next % i*st.<next9
i*st.<next % tmp9
tmp(.<next % i*st9
'
..after s"appin "e2ve c#aned our iterator address3 so
..assin correct position to contnue sortin..
i*st % min9
'
..read5ust previous node before "e &ove our list pointer
prev % i*st9
'
return list9
'
>)-?) S,-+
Merge sort takes advantage of the ease of merging already sorted lists into a new sorted list. It starts
by comparing every two elements (i.e., 1 with 2, then 3 with 4... and swapping them if the first
sho!ld come after the second. It then merges each of the res!lting lists of two into lists of fo!r, then
merges those lists of fo!r, and so on" !ntil at last two lists are merged into the final sorted list. #f
the algorithms described here, this is the first that scales well to very large lists, beca!se its worst$
case r!nning time is #(n log n.
%lgorithm&
In each pass, we are merging lists of si'e K into lists of si'e 2K. (Initially K e(!als 1. )o we start
by pointing a temporary pointer p at the head of the list, and also preparing an empty list L which
we will add elements to the end of as we finish dealing with them. *hen&
If p is n!ll, terminate this pass.
#therwise, there is at least one element in the ne+t pair of length$, lists, so increment the
n!mber of merges performed in this pass.
-oint another temporary pointer, (, at the same place as p. )tep ( along the list by , places,
or !ntil the end of the list, whichever comes first. .et psi'e be the n!mber of elements yo!
managed to step ( past.
.et (si'e e(!al ,. /ow we need to merge a list starting at p, of length psi'e, with a list
starting at ( of length at most (si'e.
)o, as long as either the p$list is non$empty (psi'e 0 1 or the q$list is non$empty ((si'e 0 1
and ( points to something non$n!ll&
o 2hoose which list to take the ne+t element from. If either list is empty, we m!st
choose from the other one. (3y ass!mption, at least one is non$empty at this point.
If both lists are non$empty, compare the first element of each and choose the lower
one. If the first elements compare e(!al, choose from the p$list. (*his ens!res that
any two elements which compare e(!al are never swapped, so stability is
g!aranteed.
o 4emove that element, e, from the start of its list, by advancing p or ( to the ne+t
element along, and decrementing psi'e or (si'e.
o %dd e to the end of the list . we are b!ilding !p.
/ow we have advanced p !ntil it is where ( started o!t, and we have advanced ( !ntil it is
pointing at the ne+t pair of length$, lists to merge. )o set p to the val!e of (, and go back to
the start of this loop.
%s soon as a pass like this is performed and only needs to do one merge, the algorithm terminates,
and the o!tp!t list L is sorted. #therwise, do!ble the val!e of K, and go back to the beginning. *his
proced!re only !ses forward links, so it doesn5t need a do!bly linked list. If it does have to deal with
a do!bly linked list, the only place this matters is when adding another item to L. 6ealing with a
circ!larly linked list is also possible. 7o! 8!st have to be caref!l when stepping along the list. *o
deal with the ambig!ity between p==head meaning yo!5ve 8!st stepped off the end of the list, and
p==head meaning yo!5ve only 8!st started, I !s!ally !se an alternative form of the 9step9
operation& first step p to its s!ccessor element, and then reset it to n!ll if that step made it become
e(!al to the head of the list.
(7o! can (!ickly de$circ!larise a linked list by finding the second element, and then breaking the
link to it from the first, b!t this moves the whole list ro!nd by one before the sorting process. *his
wo!ldn5t matter $ we are abo!t to sort the list, after all $ e+cept that it makes the sort !nstable.
2omple+ity&
.ike any self$respecting sort algorithm, this has r!nning time O(N log N). 3eca!se this is Merge
sort, the worst$case r!nning time is still O(N log N)" there are no pathological cases.
%!+iliary storage re(!irement is small and constant (i.e. a few variables within the sorting ro!tine.
*hanks to the inherently different behavio!r of linked lists from arrays, this Merge sort
implementation avoids the O(N) a!+iliary storage cost normally associated with the algorithm.
:!nction to sort a linked list&
p!blic static void merge)ort( .inked.ist my.ist;
.inked.ist left, right"
.istIterator iter < my.ist.listIterator(1, leftIter, rightIter"
int si'e < my.ist.si'e("
si'e.eft < si'e=2, inde+"
2omparable left>al!e, right>al!e"
if(si'e?2 ret!rn"
left < new .inked.ist("
for(inde+ < 1"inde+?si'e.eft"ind+@@
;
left.add.ast((2omparableiter.ne+t("
iter.remove("A
right < my.ist.clone("
my.ist.clear("
merge)ort(left"
merge)ort(right"
leftIter < left.listIterator(1"
left>al!e < (2omparable lefteIter.ne+t("
rightIter < right.listIterator(1"
right>al!e < (2omparablerightIter.ne+t("
while(left>al!eB< n!ll CC right>al!eB< n!ll;
if(right>al!e.compare*o(left>al!e?1;
my.ist.add.ast(right>al!e"
if(rightIter.has/e+t(
right>al!e < (2omparablerightIter.ne+t("
else
right>al!e < n!ll"
A
else
;
my.ist.add.ast(left>al!e"
if(leftIter.has/e+t(
left>al!e < (2omparableleftIter.ne+t("
else
left>al!e < n!ll"
A
A
if(left>al!e<<n!ll
;
my.ist.add.ast(right>al!e"
while(rightIter.has/e+t(
my.ist.add.asty(2omparablerightIter.ne+t("
A
Dlse
;
my.ist.add.ast(left>al!e"
while(leftIter.has/e+t(
my.ist.add.ast(2omparableleftIter.ne+t("
A
A
Eeap )ort
Eeap sort is a m!ch more efficient version of selection sort. It also works by determining the largest
(or smallest element of the list, placing that at the end (or beginning of the list, then contin!ing
with the rest of the list, b!t accomplishes this task efficiently by !sing a data str!ct!re called a heap,
a special type of binary tree. #nce the data list has been made into a heap, the root node is
g!aranteed to be the largest (or smallest element. Fhen it is removed and placed at the end of the
list, the heap is rearranged so the largest element remaining moves to the root. Gsing the heap,
finding the ne+t largest element takes O(log n) time, instead of O(n) for a linear scan as in simple
selection sort. *his allows Eeapsort to r!n in O(n log n) time, and this is also the worst case
comple+ity.
:!nction to sort a linked list&
p!blic class Eeap ;
private 8ava.!til.%rray.ist list < new 8ava.!til.%rray.ist("
=HH 2reate a defa!lt heap H=
p!blic Eeap( ;
A
=HH 2reate a heap from an array of ob8ects H=
p!blic Eeap(DIJ ob8ects ;
for (int i < 1" i ? ob8ects.length" i@@
add(ob8ectsIiJ"
A
=HH %dd a new ob8ect into the heap H=
p!blic void add(D new#b8ect ;
list.add(new#b8ect" == %ppend to the heap
int c!rrentInde+ < list.si'e( $ 1" == *he inde+ of the last node
while (c!rrentInde+ 0 1 ;
int parentInde+ < (c!rrentInde+ $ 1 = 2"
== )wap if the c!rrent ob8ect is greater than its parent
if (list.get(c!rrentInde+.compare*o(
list.get(parentInde+ 0 1 ;
D temp < list.get(c!rrentInde+"
list.set(c!rrentInde+, list.get(parentInde+"
list.set(parentInde+, temp"
A
else
break" == the tree is a heap now
c!rrentInde+ < parentInde+"
A
A
=HH 4emove the root from the heap H=
p!blic D remove( ;
if (list.si'e( << 1 ret!rn n!ll"
D removed#b8ect < list.get(1"
list.set(1, list.get(list.si'e( $ 1"
list.remove(list.si'e( $ 1"
int c!rrentInde+ < 1"
while (c!rrentInde+ ? list.si'e( ;
int left2hildInde+ < 2 H c!rrentInde+ @ 1"
int right2hildInde+ < 2 H c!rrentInde+ @ 2"
== :ind the ma+im!m between two children
if (left2hildInde+ 0< list.si'e( break" == *he tree is a heap
int ma+Inde+ < left2hildInde+"
if (right2hildInde+ ? list.si'e( ;
if (list.get(ma+Inde+.compare*o(
list.get(right2hildInde+ ? 1 ;
ma+Inde+ < right2hildInde+"
A
A
== )wap if the c!rrent node is less than the ma+im!m
if (list.get(c!rrentInde+.compare*o(
list.get(ma+Inde+ ? 1 ;
D temp < list.get(ma+Inde+"
list.set(ma+Inde+, list.get(c!rrentInde+"
list.set(c!rrentInde+, temp"
c!rrentInde+ < ma+Inde+"
A
else
break" == *he tree is a heap
A
ret!rn removed#b8ect"
A
=HH Ket the n!mber of nodes in the tree H=
p!blic int get)i'e( ;
ret!rn list.si'e("
A
A
L!ick sort
L!icksort is a divide and con(!er algorithm which relies on a partition operation& to partition an
array an element called a pivot is selected. %ll elements smaller than the pivot are moved before it
and all greater elements are moved after it. *his can be done efficiently in linear time and in$place.
*he lesser and greater s!blists are then rec!rsively sorted. Dfficient implementations of (!icksort
(with in$place partitioning are typically !nstable sorts and somewhat comple+, b!t are among the
fastest sorting algorithms in practice. *ogether with its modest #(log n space !sage, (!icksort is
one of the most pop!lar sorting algorithms and is available in many standard programming libraries.
*he most comple+ iss!e in (!icksort is choosing a good pivot element" consistently poor choices of
pivots can res!lt in drastically slower #(nM performance, if at each step the median is chosen as the
pivot then the algorithm works in #(n log n. :inding the median however, is an #(n operation on
!nsorted lists and therefore e+acts its own penalty with sorting

%lgorithm&
If the array contains only one element or 'ero elements then the array is sorted.
If the array contains more than one element then&
)elect an element from the array. *his element is called the 9pivot element9. :or e+ample
select the element in the middle of the array.
%ll elements which are smaller than the pivot element are placed in one array and all
elements which are larger are placed in another array.
)ort both arrays by rec!rsively applying L!icksort to them.
2ombine the arrays
:!nction to sort a linked list&
p!blic class L!ick)ort4ec!sion.inked.ist
;
p!blic static void (!ick)(int start, int finish, /ode head, /ode tail
;
int left < start"
int right < finish"
/ode pivot < head"
for(int i < 1" i ? ((left@right=2" i@@
;
pivot < pivot.ne+t"
A
/ode temp < new /ode("
/ode left/ < head"
/ode right/ < head"
while(right 0 left
;
left/ < head"
for(int i < 1" i ? left" i@@
;
left/ < left/.ne+t"
A
while ((left/.name.compare*oIgnore2ase((pivot.name?1
;
left < left @ 1"
left/ < left/.ne+t"
A
right/ < head"
for(int i < 1" i ? right" i@@
;
right/ < right/.ne+t"
A
while ((pivot.name.compare*oIgnore2ase((right/.name?1
;
right < right $ 1"
right/ < head"
for(int i < 1" i ? right" i@@
;
right/ < right/.ne+t"
A
A
if ( left ?< right

;
temp.name < left/.name"
left/.name < right/.name"
right/.name < temp.name"
left < left @1"
left/ < left/.ne+t"
right < right $1"
right/ < head"
for(int i < 1" i ? right" i@@
;
right/ < right/.ne+t"
A
int si'e < 1"
temp < head"
while (tempB<tail
;
temp < temp.ne+t"
si'e@@"
A
temp < head"
while(temp B< tail
;
)ystem.o!t.print(temp.name @ 9, 9"
temp < temp.ne+t"
A
)ystem.o!t.println(tail.name @ 9.9"
A
A
if(start ? right
(!ick)(start, right, head, tail"
if(left ? finish
(!ick)(left, finish, head, tail"
A
p!blic static void main()tringIJ args
;
/ode head < new /ode("
/ode tail < new /ode("
/ode a < new /ode("
/ode b < new /ode("
/ode c < new /ode("
head.name < 949"
tail.name < 969"
a.name < 9N9"
b.name < 929"
c.name < 9-9"
head.ne+t < a"
a.ne+t < b"
b.ne+t < c"
c.ne+t < tail"
int si'e < 1"
/ode temp < head"
while (tempB< tail
;
temp < temp.ne+t"
si'e@@"
A

(!ick)(1,si'e,head,tail"
A

A
4eferences
O%rtificial IntelligenceP, Dlaine 4ich and ,evin ,night, 2111, McKraw$Eill
OIntelligent Qava %pplicationsP, Mark Fatson, 211R, Morgan ,a!fmann -!blishers
6echter, 4 and -earl, Q, (1RST, Kenerali'ed 3est$:irst )earch )trategies and the #ptimality of %H,
Qo!rnal of the %ssociation for 2omp!ting Machinery, 32, T1T$T3U.
-earl, Q. (1RS4, Ee!ristics& Intelligent )earch )trategies for 2omp!ter -roblem )olving 4eading,
M%& %ddison$Fesley.

Você também pode gostar