320 likes | 441 Views
Sorting: MERGESORT. Vogliamo ordinare lista (a 1 ,…,a n ). Dividi lista in 2 sottoliste aventi (quasi) la stessa dimensione: (a 1 ,a 3 ,a 5 ,…) e (a 2 ,a 4 ,…), (SPLIT) 2. Ordina le due liste separatamente (MERGESORT) 3. Fondi le due liste ottenute (ordinate) in una
E N D
Sorting: MERGESORT • Vogliamo ordinare lista (a1,…,an). • 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)
MERGE (di due liste ordinate L1,L2 M) Algoritmo dipende dalla rappresentazione delle liste UsiamoLISTE A PUNTATORI: ogni elemento della lista è una struttura typedef struct CELL *LIST struct CELL{ int element /* elemento della lista*/ LIST next /* puntatore alla successiva struttura (elemento)*/ } (a1,a2,…,an) a1 a2 … an
MERGE (di due liste ordinate L1,L2 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; • } • }
MERGE (di due liste ordinate L1,L2 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; • } • }
MERGE (di due liste ordinate L1,L2 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; • } • }
MERGE (di due liste ordinate L1,L2 M) 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 …} list1 a1a2 … an list2 b1 b2 … bn a2 … an list1 a1 merge b1 … bn
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p list1=merge(list1, list2) merge (2-4-7, 3-5-6-9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9) d= merge(g, d) merge(7, 6-9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9) d= merge(g, d) merge(7, 6-9) e= merge(g, e) merge(7, 9)
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9) d= merge(g, d) merge(7, 6-9) e= merge(g, e) merge(7, 9) t= merge(NULL, e)=e merge( , 9) e 9
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9) d= merge(g, d) merge(7, 6-9) e= merge(g, e) =g merge(7, 9) g 7 t
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) merge(7, 5-6-9) d= merge(g, d)=d merge(7, 6-9) d 6 e
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) merge(4-7, 5-6-9) g= merge(g, b) = b merge(7, 5-6-9) b 5 d
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p Merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2) merge(4-7,3-5-6-9) b= merge(a, b) = a merge(4-7, 5-6-9) a 4 g
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p list1=merge(list1, list2) merge (2-4-7, 3-5-6-9) a= merge(a, list2)=list2 merge(4-7,3-5-6-9) list2 3 b
MERGE (di due liste ordinate L1,L2 M) list1 2a4g7 t list2 3 b 5 d 6 e 9 p list1=merge(list1, list2) merge (2-4-7, 3-5-6-9) list1 2 a
SPLIT (di L in due liste ordinate L1,L2) L=(a1,a2, a3, a4, …, an) L1 =(a1, a3, …) , L2=(a2, a4, …) 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; } }
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 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
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
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
MERGESORT 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
MERGESORT 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 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)); } }
R.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)
R.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)
R.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)
R.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+ 4T(2m-2) = 2c 2m +4 (c 2m-2 + 2 T(2m-3))=2c 2m + c 2m+8T(2m-3) = 3c 2m+ 8T(2m-3) …… = i c 2m+ 2iT(2m-i) Scegliendo i=m=log n si ha T(n)= T(2m) = m c 2m+ 2mT(20)= m c n + n a= = c n log n + a n = O(n log n)
Correttezza 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));} } 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.