Programmeringsteknik för Ingenjörer VT06 Föreläsning 14 Dagens föreläsning • Träd • Sökning • Sortering Programmeringsteknik för ingenjörer, VT06 2 Träd Ett träd består av ett antal noder förbundna med varandra så att det inte bildas någon loop. rot delträd löv • Varje träd har en unik nod som kallas rot. Roten saknar föräldrar. • En nod som saknar barn kallas för löv. • Ett träd består av en samling delträd. Programmeringsteknik för ingenjörer, VT06 3 Binära träd rot Binära träd är en viktig undergrupp till träd. I ett binärt träd har en nod maximalt två barn. Denna egenskap gör att man lätt kan deklarera en nodstruktur för trädet bestående av ett element och två länkar (left och right). 35 35 40 25 20 30 25 20 Programmeringsteknik för ingenjörer, VT06 40 30 4 Binärt sökträd Ett binärt träd kallas sökträd om det har följande egenskaper: • Varje nod har ett unikt värde • Alla element i en nods vänstra delträd har lägre värde än noden själv. • Alla element i en nods högra delträd är större värdet än noden själv. 32 41 29 20 30 Programmeringsteknik för ingenjörer, VT06 45 5 Binärt sökträd I ett välbalanserat träd med n noder krävs max log2n steg innan man hittar ett element man söker. 1 2 I en sorterad lista med n noder krävs upp till n steg innan ett element hittas. 3 4 4 5 6 2 6 1 3 5 7 7 Programmeringsteknik för ingenjörer, VT06 6 Binärt sökträd Algoritm för att sätta in ett element i ett binärt sökträd: 1. Om noden är tom, sätt in elementet i noden 2. Annars ska den sättas in i något av nodens delträd: 1. Om elementet är mindre än noden, sätt in den i vänster delträd. 2. Om elementet är större än noden, sätt in den i höger delträd. 3. Om elementet är samma som noden, skippa insättningen. Observera att algoritmen är rekursiv….. Programmeringsteknik för ingenjörer, VT06 7 Binärt sökträd Algoritm för att ta bort ett element i ett binärt sökträd: 1. Om noden är ett löv, ta bort noden. 2. Om noden bara har ett barn, ta bort noden och länka ihop föräldern och barnet. 3. Om noden har två barn: 1. Hitta den minsta noden i det högra delträdet. 2. Ta bort den minsta noden och sätt in den på platsen för noden som ska tas bort. Programmeringsteknik för ingenjörer, VT06 8 Sökning Ofta har man data i arrayer. Det finns primärt två sätt att söka data i en array. • Linjär sökning (sorterad/osorterad data) • Binär sökning (sorterad data) Programmeringsteknik för ingenjörer, VT06 9 Sortering Finns ett flertal algoritmer, några vanliga: • Selection sort (enkel att implementera, långsam) • Bubble sort (enkel att implementera, långsam) • Quicksort (Rekursiv, snabb) Data sorteras för att snabba upp sökning. Programmeringsteknik för ingenjörer, VT06 10 Selection sort Tillvägagångssätt: – Hitta minsta elementet i arrayen – Sätt elementet först i arrayen (byt plats med elementet som är först). – Ta ut en delarray som består av alla element utom första. (som är på rätt plats). – Börja om och fortsätt tills listan är sorterad. Fördelar: • Enkel • Jobbar på en uppsättning data. Nackdelar: • Långsam (n2) komplexitet Programmeringsteknik för ingenjörer, VT06 11 double SelectionSort(int list[],int len){ clock_t t1,t2; int i,j,smallest,tmp; t1=clock(); printf("<SelectionSort>\n"); for(j=0;j<len;j++){ smallest=j; for(i=j;i<len;i++) if (list[i]<list[smallest]) smallest=i; tmp=list[j]; list[j]=list[smallest]; list[smallest]=tmp; } t2=clock(); return(difftime(t2,t1)); } Programmeringsteknik för ingenjörer, VT06 12 Bubble sort for i=0 to n-1 do for j=0 to n-1 do if (el[j] > el[j+1]) do swap(el[j],el[j+1]) Fördelar: • Enkel • Jobbar på en uppsättning data. Nackdelar: • Långsam (n2) komplexitet Programmeringsteknik för ingenjörer, VT06 13 double BubbleSort(int list[], int len){ clock_t t1,t2; int i,j,tmp; t1=clock(); printf("<BubbleSort>\n"); for (j=0;j<len;j++){ for(i=0;i<len-1;i++) if(list[i]>list[i+1]){ tmp=list[i]; list[i]=list[i+1]; list[i+1]=tmp; } } t2=clock(); return(difftime(t2,t1)); } Programmeringsteknik för ingenjörer, VT06 14 Quick Sort • Bra sorteringsalgoritm (n log n) komplexitet • Algoritm: – Välj ut ett ett värde ur listan (pivotelementet) godtyckligt vilket – Placera alla element mindre än pivotelementet i början av listan och alla element större än pivotelementet i slutet på listan. – Anropa sedan QuickSort rekursivt för början av listan och för slutet av listan. Programmeringsteknik för ingenjörer, VT06 15 void MyQuickSort(int list[], int len){ int smaller[len],slen=0,llen=0,larger[len], pivot=list[0],i,j,equal[len],elen=0; if(len<=1) return; for(i=0;i<len;i++){ if(list[i]<pivot){ smaller[slen]=list[i]; slen++; } if(list[i]==pivot){ equal[elen]=list[i]; elen++; } if(list[i]>pivot){ larger[llen]=list[i]; llen++; } } MyQuickSort(smaller,slen); MyQuickSort(larger,llen); double QuickSort(int list[],int len){ clock_t t1,t2; t1=clock(); MyQuickSort(list,len); t2=clock(); return(difftime(t2,t1)); } for(i=0;i<slen;i++) list[i]=smaller[i]; for(i=slen,j=0;i<slen+elen;i++,j++) list[i]=equal[j]; for(i=slen+elen,j=0;i<len;i++,j++) list[i]=larger[j]; } Programmeringsteknik för ingenjörer, VT06 16 Komplexitet • Det är lätt att inbilla sig att skillnaden mellan n2 och nlog n - komplexitet enbart är av akademiskt intresse • Men studera följande graf: 16 10 14 10 12 10 10 10 8 10 6 10 4 10 2 10 0 10 1 10 2 10 3 10 4 10 5 10 Programmeringsteknik för ingenjörer, VT06 6 10 7 10 8 10 17 int main(void){ double Tb,Ts,Tq; int *lista,len; printf("How many elements in list: "); scanf("%d",&len); srand(time(NULL)); lista=CreateRandomVector(len); Tb=BubbleSort(lista,len); free(lista); lista=CreateRandomVector(len); Ts=SelectionSort(lista,len); free(lista); lista=CreateRandomVector(len); Tq=QuickSort(lista,len); free(lista); printf("Method \t\tElements\tElapsed time\n"); printf("BubbleSort\t%d\t\t %9.0f\n",len,Tb); printf("SelectionSort\t%d\t\t %9.0f\n",len,Ts); printf("QuickSort\t%d\t\t %9.0f\n",len,Tq); return 0; } Programmeringsteknik för ingenjörer, VT06 18 9 10 8 10 7 10 6 10 5 10 4 10 4 10 5 10 Method BubbleSort SelectionSort QuickSort Elements 100000 100000 100000 Programmeringsteknik för ingenjörer, VT06 Elapsed time 269480000 70320000 150000 19 • Vid listlängd på 100000 element är BubbleSort 1797 gånger långsammare än QuickSort • Det är bättre att ha en naiv implementation av en bra algoritm än en smart implementation av en dålig algoritm…… Programmeringsteknik för ingenjörer, VT06 20