+ All Categories
Home > Documents > Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi...

Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi...

Date post: 01-May-2015
Category:
Upload: elena-rocco
View: 212 times
Download: 0 times
Share this document with a friend
32
Sorting: MERGESORT Sorting: MERGESORT Vogliamo ordinare lista (a1,…,an). 1. Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a1,a3,a5,…) e (a2,a4,…), (SPLIT) 2. Ordina le due liste separatamente (MERGESORT) 3. Fondi le due liste ottenute (ordinate) in una unica lista ordinata (MERGE)
Transcript
Page 1: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

Sorting: MERGESORTSorting: MERGESORT

Vogliamo ordinare lista (a1,…,an).

1. Dividi lista in 2 sottoliste aventi (quasi) la stessa

dimensione: (a1,a3,a5,…) e (a2,a4,…), (SPLIT)

2. Ordina le due liste separatamente (MERGESORT)

3. Fondi le due liste ottenute (ordinate) in una unica lista ordinata (MERGE)

Page 2: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

Algoritmo dipende dalla rappresentazione delle liste

Usiamo LISTE A PUNTATORI:

ogni elemento della lista è una struttura typedef struct CELL *LISTstruct CELL{ int element /* elemento della lista*/ LIST next /* puntatore alla successiva

struttura (elemento)*/

}

(a1,a2,…,an) a1 a2 … an

Page 3: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

-Trova il minimo tra il primo elemento di L1 e di L2,

rimuovilo dalla lista di appartenenza ed aggiungilo ad M.

- Ripeti

- LIST merge (LIST list1, LIST list2){ if (list1==NULL) return list2 else if (list2==NULL) return list1 else if (list1->element <= list2 -> element)

/* entrambe le liste non vuote ed il primo elemento di list1 è minore del primo di list2*/

{ list1->next=merge(list1->next, list2); return list1; } else /*entrambe le liste non vuote ed il primo

elemento di list2 è minore del primo di list1*/

{ list2->next=merge(list1, list2->next); return list2; } }

Page 4: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

-Trova il minimo tra il primo elemento di L1 e di L2,

rimuovilo dalla lista di appartenenza ed aggiungilo ad M.

- Ripeti

- LIST merge (LIST list1, LIST list2){ if (list1==NULL) return list2 else if (list2==NULL) return list1 else if (list1->element <= list2->element)

/* entrambe le liste non vuote ed il primo elemento di list1 è minore del primo di list2*/

{ list1->next=merge(list1->next, list2); return list1; } else /*entrambe le liste non vuote ed il primo

elemento di list2 è minore del primo di list1*/

{ list2->next=merge(list1, list2->next); return list2; } }

Page 5: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

-Trova il minimo tra il primo elemento di L1 e di L2,

rimuovilo dalla lista di appartenenza ed aggiungilo ad M.

- Ripeti

- LIST merge (LIST list1, LIST list2){ if (list1==NULL) return list2 else if (list2==NULL) return list1 else /* entrambe le liste non vuote*/ if (list1->element <= list2->element)

/* entrambe le liste non vuote ed il primo elemento di list1 è minore del primo di list2*/

{ list1->next=merge(list1->next, list2); return list1; } else /*entrambe le liste non vuote ed il primo

elemento di list2 è minore del primo di list1*/

{ list2->next=merge(list1, list2->next); return list2; } }

Page 6: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

LIST merge (LIST list1, LIST list2) {if (list1==NULL) return list2else if (list2==NULL) return list1 else if ( list1->element <= list2->element ) {/* entrambe le liste non vuote ed il primo

elemento di list1 è minore del primo di list2*/ list1->next=merge(list1->next, list2); return list1;} else …} list1 a1 a2 … an

list2 b1 b2 … bn

a2 … an list1 a1 merge

b1 … bn

Page 7: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

list1=merge(list1, list2) merge (2-4-7, 3-5-6-9)

Page 8: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

Page 9: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

Page 10: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

Page 11: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

= merge(, ) merge(7, 6-9)

Page 12: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

= merge(, ) merge(7, 6-9)

= merge(, ) merge(7, 9)

Page 13: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7

list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

= merge(, ) merge(7, 6-9)

= merge(, ) merge(7, 9)

= merge(NULL, )= merge( , 9) 9

Page 14: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

= merge(, ) merge(7, 6-9)

= merge(, ) = merge(7, 9) 7

Page 15: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) merge(7, 5-6-9)

= merge(, )= merge(7, 6-9) 6

Page 16: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) merge(4-7, 5-6-9)

= merge(, ) = merge(7, 5-6-9) 5

Page 17: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

Merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2) merge(4-7,3-5-6-9)

= merge(, ) = merge(4-7, 5-6-9) 4

Page 18: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

list1=merge(list1, list2) merge (2-4-7, 3-5-6-9)

merge(list2)=list2 merge(4-7,3-5-6-9) list2 3

Page 19: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGE (di due liste ordinate LMERGE (di due liste ordinate L11,L,L22 M) M)

list1 2 4 7 list2 3 5 6 9

list1=merge(list1, list2) merge (2-4-7, 3-5-6-9) list1 2

Page 20: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

SPLIT (di L in due liste ordinate LSPLIT (di L in due liste ordinate L11,L,L22))

LIST Split (LIST list){ List pSecondcell;if (list==NULL) return NULLelse if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell; }}

L=(a1,a2, a3, a4, …, an) L1 =(a1, a3, …) , L2 =(a2, a4, …)

Page 21: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

SPLIT (di L in due liste ordinate L1,L2)SPLIT (di L in due liste ordinate L1,L2)

LIST Split (LIST list){ List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}}

list a1 a2 a3 … an

Page 22: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

SPLIT (di L in due liste ordinate L1,L2)SPLIT (di L in due liste ordinate L1,L2)

LIST Split (LIST list){ List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}}

list a1 a2 a3 … an

pSecondcell

Page 23: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

SPLIT (di L in due liste ordinate L1,L2)SPLIT (di L in due liste ordinate L1,L2)

LIST Split (LIST list){ List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}}

list a1 a2 a3 … an

pSecondcell

Page 24: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

SPLIT (di L in due liste ordinate L1,L2)SPLIT (di L in due liste ordinate L1,L2)

LIST Split (LIST list){ List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}}

list a1 a2 a3 … an

Split di

pSecondcell

Page 25: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGESORTMERGESORT

BASE: Se la lista contiene 0 o 1 elemento, stop Ind.: Split di (a1,a2,…) in (a1,a3,…) e (a2,a4,…) Mergesort delle due liste separatamente Merge delle 2 liste ordinate

Page 26: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

MERGESORTMERGESORT

LIST Mergesort (LIST list){ List SecondList;if (list==NULL) return NULLelse if (list->next==NULL) return list else {/* list contiene almeno 2 elementi (da ordinare)*/ SecondList=split(list); return merge(mergesort(list),mergesort(ScondList)); }}

BASE: Se la lista contiene 0 o 1 elemento, stop Ind.: Split di (a1,a2,…) in (a1,a3,…) e (a2,a4,…) Mergesort delle due liste separatamente Merge delle 2 liste ordinate

Page 27: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

R.T. della funzione SPLITR.T. della funzione SPLIT

LIST Split (LIST list){ List pSecondcell; if (list==NULL) return NULL else if (list->Next==NULL) return NULL else {/* list contiene almeno 2 elementi*/ pScondcell=list->next; list->next = pSecondcell->next; pSecondcell->next=split(pSecondcell->next); return pSecondcell;}}

Sia n=|list|. Si ha la relazione di ricorrenza T(0)=T(1)=O(1)

T(n)=c+T(n-2), per n>1

Quindi T(n)=O(n)

Page 28: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

R.T. del MERGER.T. del MERGE

LIST merge (LIST list1, LIST list2){ if (list1==NULL) return list2 else if (list2==NULL) return list1 else if (list1->element <= list2 -> element)

{ list1->next=merge(list1->next, list2); return list1; } else { list2->next=merge(list1, list2->next); return list2;} }

Siano n1=|list1|, n2=|list2|, n=n1+n2. Si ha la relazione di ricorrenza T(0)=T(1)=O(1) (almeno 1 lista vuota)

T(n)=c+T(n-1), per n>1

Quindi T(n)=O(n)

Page 29: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

R.T. MERGESORTR.T. MERGESORT

LIST Mergesort (LIST list){List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da

ordinare)*/ {SecondList=split(list); return

merge(mergesort(list),mergesort(ScondList));}}

Sia n=|list|. Si ha la relazione di ricorrenza T(0)=T(1)=O(1) (list contiene 0 o 1 elemento)

T(n)=O(n) + O(n) +T(n/2) +T(n/2) =O(n) + 2 T(n/2), per n>1

Quindi T(n)=O(n log n)

Page 30: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

R.T. MERGESORTR.T. MERGESORT

T(0)=T(1)=O(1) T(n)=c n + 2 T(n/2), per n>1

Si assuma per semplicità che n=2m (cioè m=log n)

T(2m)=c 2m + 2 T(2m-1) =c 2m + 2 (c 2m-1 + 2 T(2m-2))= c 2m + c 2m +4

T(2m-2) = 2c 2m + 4 T(2m-2) = 2c 2m +4 (c 2m-2 + 2 T(2m-3))=2c 2m + c

2m+8T(2m-3) = 3c 2m + 8 T(2m-3) …… = i c 2m + 2i T(2m-i)

Scegliendo i=m=log n si ha T(n)= T(2m) = m c 2m + 2m T(20)= m c n + n a= = c n log n + a n = O(n log n)

Page 31: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

Correttezza MERGESORTCorrettezza MERGESORTLIST Mergesort (LIST list){List SecondList; if (list==NULL) return NULL else if (list->next==NULL) return list else /* list contiene almeno 2 elementi (da ordinare)*/ {SecondList=split(list); return merge(mergesort(list),mergesort(ScondList));}}

Assumiamo correttezza delle funz.split e merge (esercizio)

Per induzione completa su n=|list|.Base. Se n=0 o n=1, restituisce lista inalterata, ok.

Passo (n>1). Assumiamo per i.i. mergesort(list), mergesort(ScondList) restituiscono liste input ordinate.

Quindi Split divide gli elementi lista input con n elementi tra list e Secondlist; mergesort(list),mergesort(ScondList) ordina le liste;

Merge fonde le liste restituendo in output una lista ordinata contenete gli stessi n elementi della lista input.

Page 32: Sorting: MERGESORT Vogliamo ordinare lista (a 1,…,a n ). 1.Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1,a 3,a 5,…) e (a 2,a 4,…),

Recommended