logo

Combina l'ordenació en Python

L'ordenació combinada és similar a l'algoritme d'ordenació ràpida, ja que treballa amb el concepte de dividir i conquerir. És un dels algorismes d'ordenació més populars i eficients. És el millor exemple per a la categoria d'algorismes de dividir i conquerir.

Divideix la llista donada en les dues meitats, s'anomena per les dues meitats i després fusiona les dues meitats ordenades. Definim el combinar () funció utilitzada per fusionar dues meitats.

Les subllistes es divideixen una i altra vegada en meitats fins que obtenim l'únic element cadascuna. A continuació, combinem la parella de llistes d'un element en dues llistes d'elements, ordenant-les en el procés. Els dos parells d'elements ordenats es fusionen en les quatre llistes d'elements, i així successivament fins que aconseguim la llista ordenada.

Concepte d'ordenació combinada

Vegem el següent diagrama d'ordenació de combinació.

Hem dividit la llista donada en les dues meitats. La llista no es pot dividir en parts iguals, no importa gens.

L'ordenació de combinacions es pot implementar mitjançant les dues maneres: enfocament de dalt a baix i enfocament de baix a dalt. Utilitzem l'enfocament de dalt a baix a l'exemple anterior, que és l'ordenació de combinació que s'utilitza més sovint.

L'enfocament de baix a dalt proporciona més optimització que definirem més endavant.

La part principal de l'algorisme és com combinem les dues subllistes ordenades. Combinem les dues llistes de combinació ordenades.

  • A: [ 2 , 4, 7, 8]
  • B: [ 1 , 3, 11]
  • ordenat: buit

En primer lloc, observem el primer element d'ambdues llistes. Trobem que el primer element de B és més petit, així que ho afegim a la nostra llista ordenada i avancem a la llista B.

  • A: [ 2 , 4, 7, 8]
  • B: [1, 3 , 11]
  • Ordenat: 1

Ara mirem el següent parell d'elements 2 i 3. 2 és més petit, així que l'afegim a la nostra llista ordenada i avancem a la llista.

  • A: [ 2 , 4, 7, 8]
  • B: [1, 3 , 11]
  • Ordenat: 1

Continueu aquest procés i acabem amb la llista ordenada de {1, 2, 3, 4, 7, 8, 11}. Hi pot haver dos casos especials.

màquina d'estats finits

Què passa si les dues subllistes tenen els mateixos elements? En aquest cas, podem moure una de les subllistes i afegir l'element a la llista ordenada. Tècnicament, podem avançar a les dues subllistes i afegir els elements a la llista ordenada.

No ens queda cap element en una subllista. Quan acabem la llista en una subllista, només cal afegir l'element del segon un darrere l'altre.

Hem de recordar que podem ordenar l'element en qualsevol ordre. Ordenam la llista donada en ordre ascendent, però podem ordenar fàcilment en ordre descendent.

Implementació

L'algorisme d'ordenació de combinació s'implementa mitjançant l'enfocament de dalt a baix. Pot semblar una mica difícil, així que elaborarem els detalls de cada pas. Aquí, implementarem aquest algorisme en dos tipus de col·leccions: la llista d'elements enters (normalment s'utilitza per introduir l'ordenació) i un objecte personalitzat (un escenari més pràctic i realista).

enumeracions java

Matriu d'ordenació

El concepte principal d'algorisme és dividir (sub)llista en meitats i ordenar-les de forma recursiva. Continuem el procés fins que acabem llistes que només tenen un element. Entenem la següent funció per a la divisió:

 def merge_sort(array, left_index, right_index): if left_index >= right_index: return middle = (left_index + right_index)//2 merge_sort(array, left_index, middle) merge_sort(array, middle + 1, right_index) merge(array, left_index, right_index, middle) 

El nostre objectiu principal és dividir la llista en subparts abans de l'ordenació. Hem d'obtenir el valor sencer per tal que utilitzem l'operador // per als nostres índexs.

Entendrem el procediment anterior seguint els passos.

  • El primer pas és crear còpies de llistes. La primera llista conté les llistes de [índex_esquerra,...,centre] i el segon de [mig+1,?,index_dreta] .
  • Travessem les dues còpies de la llista utilitzant el punter, seleccionem el valor més petit dels dos valors i els afegim a la llista ordenada. Un cop afegim l'element a la llista i avancem a la llista ordenada independentment.
  • Afegiu els elements restants de l'altra còpia a la matriu ordenada.

Implementem l'ordenació de combinació al programa Python.

Programa Python

 # Here, we are declaring the function to divide the lists in to the two sub lists # Here, we are passing the list1, left index, right index as the parameters def merge_sort(list1, left_index, right_index): if left_index &gt;= right_index: # here, we are checking the if condition return middle = (left_index + right_index)//2 # Here, we are finding the middle of the given two numbers merge_sort(list1, left_index, middle) # Here, we are calling the merge sort function till the middle number we got merge_sort(list1, middle + 1, right_index) # Here, we are calling the merge sort function till the end of the list i.e., right index merge(list1, left_index, right_index, middle) # Here, we are calling the merge function to merge the divided list using the merge # sort function above # Here, we are defining a function for merge the list after dividing def merge(list1, left_index, right_index, middle): # Here, we are creating subparts of a lists left_sublist = list1[left_index:middle + 1] right_sublist = list1[middle+1:right_index+1] # Here, we are initializing the values for variables that we use to keep # track of where we are in each list1 left_sublist_index = 0 right_sublist_index = 0 sorted_index = left_index # Here, we are traversing the both copies until we get run out one element while left_sublist_index <len(left_sublist) 1 and right_sublist_index < len(right_sublist): # here, we are declaring a while loop if our left_sublist has the smaller element, put it in sorted part then move forward (by increasing pointer) left_sublist[left_sublist_index] checking condition, is true will enter block list1[sorted_index]="left_sublist[left_sublist_index]" left_sublist_index="left_sublist_index" + otherwise add into right sublist else: moving sorted_index="sorted_index" go through remaining elements them len(left_sublist): len(right_sublist):# list1="[44," 65, 2, 3, 58, 14, 57, 23, 10, 1, 7, 74, 48] print('the given list before performing merge sort is: ', list1) this input unsorted array by user merge_sort(list1, 0, len(list1) -1) after is:', printing amd functions pre> <p> <strong>Output:</strong> </p> <pre> The given list before performing the merge sort is: [44, 65, 2, 3, 58, 14, 57, 23, 10, 1, 7, 74, 48] The given list after performing the merge sort is: [1, 2, 3, 7, 10, 14, 23, 44, 48, 57, 58, 65, 74] </pre> <h2>Sorting Custom Objects</h2> <p>We can also sort the custom objects by using the <a href="/python-tutorial-python-programming-language">Python</a> class. This algorithm is almost similar to the above but we need to make it more versatile and pass the comparison function.</p> <p>We will create a custom class, Car and add a few fields to it. We make few changes in the below algorithm to make it more versatile. We can do this by using the lambda functions.</p> <p>Let&apos;s understand the following example.</p> <h3>Python Program</h3> <pre> class Car: # here, we are declaring a class named car def __init__(self, make, model, year): self.make = make # Here, we are using the self to declare the make variables locally self.model = model # Here, we are using the self to declare the model variables locally self.year = year # Here, we are using the self to declare the year variables locally def __str__(self): return str.format(&apos;Make: {}, Model: {}, Year: {}&apos;, self.make, self.model, self.year) # Here, we are returning the format of the strings given def merge(list1, l, r, m, comp_fun): # Here, we are defining a function for merge the list using the compound function left_copy = list1[l:m + 1] # here, we are coping the left part of the list r_sublist = list1[m+1:r+1] # here, we are coping the right part of the list left_copy_index = 0 # here, we are coping the left part indexes of the list r_sublist_index = 0 # here, we are coping the right part indexes of the list sorted_index = l while left_copy_index <len(left_copy) 1 and r_sublist_index < len(r_sublist): # here, we are declaring a while loop using the comp_fun instead of simple comparison operator if comp_fun(left_copy[left_copy_index], r_sublist[r_sublist_index]): checking condition, it is true then will enter block list1[sorted_index]="left_copy[left_copy_index]" left_copy_index="left_copy_index" + else: condition false else sorted_index="sorted_index" len(left_copy): <len(r_sublist): def merge_sort(list1, l, r, comp_fun): merge sort function to given list l>= r: # Here, we are checking the if condition, if it is true then we will enter the block return m = (l + r)//2 # here, we are finding the middle element of the list merge_sort(list1, l, m, comp_fun) # Here, we are calling the merge sort function till the middle number we got merge_sort(list1, m + 1, r, comp_fun) # Here, we are calling the merge sort function from the middle number we got merge(list1, l, r, m, comp_fun) # Here, we are calling the merge function to merge the divided list using the merge # sort function above car1 = Car(&apos;Renault&apos;, &apos;33 Duster&apos;, 2001) car2 = Car(&apos;Maruti&apos;, &apos;Maruti Suzuki Dzire&apos;, 2015) car3 = Car(&apos;Tata motor&apos;, &apos;Jaguar&apos;, 2004) car4 = Car(&apos;Cadillac&apos;, &apos;Seville Sedan&apos;, 1995) list1 = [car1, car2, car3, car4] merge_sort(list1, 0, len(list1) -1, lambda carA, carB: carA.year <carb.year) print('cars sorted by year:') for car in list1: # here, we are declaring the loop to iterate through list1 print(car) printing all data of and list print() merge_sort(list1, 0, len(list1) -1, lambda cara, carb: cara.make < carb.make) make:') pre> <p> <strong>Output:</strong> </p> <pre> Cars sorted by year: Make: Cadillac, Model: Seville Sedan, Year: 1995 Make: Renault, Model: 33 Duster, Year: 2001 Make: Tata motor, Model: Jaguar, Year: 2004 Make: Maruti, Model: Maruti Suzuki Dzire, Year: 2015 Cars sorted by make: Make: Cadillac, Model: Seville Sedan, Year: 1995 Make: Maruti, Model: Maruti Suzuki Dzire, Year: 2015 Make: Renualt, Model: 33 Duster, Year: 2001 Make: Tata motor, Model: Jaguar, Year: 2004 </pre> <h2>Optimization</h2> <p>We can improve the performance of the merge sort algorithm. First let&apos;s understand the difference between the top-down and bottom-up merge sort. The bottom-up approach sorts the elements of adjacent lists iteratively where the top-down approach breaks down the lists into the two halves.</p> <p>The given list is [10, 4, 2, 12, 1, 3], instead of breaking it down into [10], [4], [2], [12], [1], [3] - we divide into the sub lists which may already sorted: [10, 4], [2], [1, 12], [3] and now are ready to sort them.</p> <p>Merge sort is inefficient algorithm in both time and space for the smaller sub lists. So, insertion sort is more efficient algorithm than the merge sort for the smaller sub lists.</p> <h2>Conclusion</h2> <p>Merge sort is popular and efficient algorithm. It is more efficient algorithm for the large lists. It does not depend on the any unfortunate decisions that lead to bad runtimes.</p> <p>There is one major demerit in the merge sort. It uses the additional memory that is used to store the temporary copies of lists before merging them. However Merge sort is widely used in the software. Its performance is fast and produces the excellent result.</p> <p>We have discussed the merge sort concept in brief and implement it both on simple integer list and on custom objects via a lambda function used for comparison.</p> <hr></carb.year)></len(left_copy)></pre></len(left_sublist)>

Ordenar objectes personalitzats

També podem ordenar els objectes personalitzats mitjançant l' Python classe. Aquest algorisme és gairebé semblant a l'anterior però hem de fer-lo més versàtil i passar la funció de comparació.

Crearem una classe personalitzada, Car i afegirem uns quants camps. Fem pocs canvis a l'algorisme següent per fer-lo més versàtil. Ho podem fer utilitzant les funcions lambda.

Entenem l'exemple següent.

Programa Python

 class Car: # here, we are declaring a class named car def __init__(self, make, model, year): self.make = make # Here, we are using the self to declare the make variables locally self.model = model # Here, we are using the self to declare the model variables locally self.year = year # Here, we are using the self to declare the year variables locally def __str__(self): return str.format(&apos;Make: {}, Model: {}, Year: {}&apos;, self.make, self.model, self.year) # Here, we are returning the format of the strings given def merge(list1, l, r, m, comp_fun): # Here, we are defining a function for merge the list using the compound function left_copy = list1[l:m + 1] # here, we are coping the left part of the list r_sublist = list1[m+1:r+1] # here, we are coping the right part of the list left_copy_index = 0 # here, we are coping the left part indexes of the list r_sublist_index = 0 # here, we are coping the right part indexes of the list sorted_index = l while left_copy_index <len(left_copy) 1 and r_sublist_index < len(r_sublist): # here, we are declaring a while loop using the comp_fun instead of simple comparison operator if comp_fun(left_copy[left_copy_index], r_sublist[r_sublist_index]): checking condition, it is true then will enter block list1[sorted_index]="left_copy[left_copy_index]" left_copy_index="left_copy_index" + else: condition false else sorted_index="sorted_index" len(left_copy): <len(r_sublist): def merge_sort(list1, l, r, comp_fun): merge sort function to given list l>= r: # Here, we are checking the if condition, if it is true then we will enter the block return m = (l + r)//2 # here, we are finding the middle element of the list merge_sort(list1, l, m, comp_fun) # Here, we are calling the merge sort function till the middle number we got merge_sort(list1, m + 1, r, comp_fun) # Here, we are calling the merge sort function from the middle number we got merge(list1, l, r, m, comp_fun) # Here, we are calling the merge function to merge the divided list using the merge # sort function above car1 = Car(&apos;Renault&apos;, &apos;33 Duster&apos;, 2001) car2 = Car(&apos;Maruti&apos;, &apos;Maruti Suzuki Dzire&apos;, 2015) car3 = Car(&apos;Tata motor&apos;, &apos;Jaguar&apos;, 2004) car4 = Car(&apos;Cadillac&apos;, &apos;Seville Sedan&apos;, 1995) list1 = [car1, car2, car3, car4] merge_sort(list1, 0, len(list1) -1, lambda carA, carB: carA.year <carb.year) print(\'cars sorted by year:\') for car in list1: # here, we are declaring the loop to iterate through list1 print(car) printing all data of and list print() merge_sort(list1, 0, len(list1) -1, lambda cara, carb: cara.make < carb.make) make:\') pre> <p> <strong>Output:</strong> </p> <pre> Cars sorted by year: Make: Cadillac, Model: Seville Sedan, Year: 1995 Make: Renault, Model: 33 Duster, Year: 2001 Make: Tata motor, Model: Jaguar, Year: 2004 Make: Maruti, Model: Maruti Suzuki Dzire, Year: 2015 Cars sorted by make: Make: Cadillac, Model: Seville Sedan, Year: 1995 Make: Maruti, Model: Maruti Suzuki Dzire, Year: 2015 Make: Renualt, Model: 33 Duster, Year: 2001 Make: Tata motor, Model: Jaguar, Year: 2004 </pre> <h2>Optimization</h2> <p>We can improve the performance of the merge sort algorithm. First let&apos;s understand the difference between the top-down and bottom-up merge sort. The bottom-up approach sorts the elements of adjacent lists iteratively where the top-down approach breaks down the lists into the two halves.</p> <p>The given list is [10, 4, 2, 12, 1, 3], instead of breaking it down into [10], [4], [2], [12], [1], [3] - we divide into the sub lists which may already sorted: [10, 4], [2], [1, 12], [3] and now are ready to sort them.</p> <p>Merge sort is inefficient algorithm in both time and space for the smaller sub lists. So, insertion sort is more efficient algorithm than the merge sort for the smaller sub lists.</p> <h2>Conclusion</h2> <p>Merge sort is popular and efficient algorithm. It is more efficient algorithm for the large lists. It does not depend on the any unfortunate decisions that lead to bad runtimes.</p> <p>There is one major demerit in the merge sort. It uses the additional memory that is used to store the temporary copies of lists before merging them. However Merge sort is widely used in the software. Its performance is fast and produces the excellent result.</p> <p>We have discussed the merge sort concept in brief and implement it both on simple integer list and on custom objects via a lambda function used for comparison.</p> <hr></carb.year)></len(left_copy)>

Optimització

Podem millorar el rendiment de l'algoritme d'ordenació combinada. Primer anem a comprendre la diferència entre l'ordenació de fusió de dalt a baix i de baix a dalt. L'enfocament de baix a dalt ordena els elements de llistes adjacents de manera iterativa, on l'enfocament de dalt a baix desglossa les llistes en les dues meitats.

La llista donada és [10, 4, 2, 12, 1, 3], en lloc de dividir-la en [10], [4], [2], [12], [1], [3] - dividim a les subllistes que ja estan ordenades: [10, 4], [2], [1, 12], [3] i ara ja estan preparats per ordenar-les.

L'ordenació combinada és un algorisme ineficient tant en el temps com en l'espai per a les subllistes més petites. Per tant, l'ordenació d'inserció és un algorisme més eficient que l'ordenació de combinació per a les subllistes més petites.

Conclusió

L'ordenació combinada és un algorisme popular i eficient. És un algorisme més eficient per a les llistes grans. No depèn de les decisions desafortunades que condueixin a temps d'execució dolents.

Hi ha un demèrit important en l'ordre de fusió. Utilitza la memòria addicional que s'utilitza per emmagatzemar les còpies temporals de les llistes abans de combinar-les. Tanmateix, l'ordenació de combinació s'utilitza àmpliament al programari. El seu rendiment és ràpid i produeix un resultat excel·lent.

Hem parlat breument del concepte d'ordenació de combinació i l'hem implementat tant en una llista d'enters simples com en objectes personalitzats mitjançant una funció lambda utilitzada per a la comparació.