logo

מיזוג מיון ב-Python

מיון מיזוג דומה לאלגוריתם המיון המהיר כפי שעובד על הרעיון של חלוקה וכבש. זהו אחד מאלגוריתמי המיון הפופולריים והיעילים ביותר. זוהי הדוגמה הטובה ביותר לקטגוריית חלוקה וכיבוש של אלגוריתמים.

הוא מחלק את הרשימה הנתונה לשני החצאים, מכנה את עצמו עבור שני החצאים ואז ממזג את שני החצאים הממוינים. אנו מגדירים את לְמַזֵג() פונקציה המשמשת למיזוג שני חצאים.

רשימות המשנה מחולקות שוב ושוב לחצאים עד שנקבל את האלמנט היחיד כל אחד. לאחר מכן אנו משלבים את צמד רשימות האלמנטים לשתי רשימות אלמנטים, וממיינים אותן תוך כדי התהליך. שני צמדי האלמנטים הממוינים מתמזגים לארבע רשימות האלמנטים, וכך הלאה עד שנקבל את הרשימה הממוינת.

מיזוג קונספט מיון

בוא נראה את דיאגרמת מיון המיזוג הבאה.

חילקנו את הרשימה הנתונה לשני החצאים. אי אפשר היה לחלק את הרשימה לחלקים שווים זה לא משנה בכלל.

ניתן ליישם מיון מיזוג באמצעות שתי הדרכים - גישה מלמעלה למטה וגישה מלמטה למעלה. אנו משתמשים בגישה מלמעלה למטה בדוגמה שלמעלה, שבה משתמשים לרוב במיון מיזוג.

הגישה מלמטה למעלה מספקת אופטימיזציה רבה יותר אותה נגדיר בהמשך.

החלק העיקרי באלגוריתם הוא כיצד אנו משלבים את שתי רשימות המשנה הממוינות. בואו נמזג את שני רשימת המיזוגים הממוינים.

  • ת: [ 2 , 4, 7, 8]
  • ב: [ 1 , 3, 11]
  • ממוין: ריק

ראשית, אנו מתבוננים באלמנט הראשון של שתי הרשימות. אנו מוצאים שהאלמנט הראשון של ה-B קטן יותר, אז אנו מוסיפים את זה לרשימה הממוינת שלנו ומתקדמים ברשימה B.

  • ת: [ 2 , 4, 7, 8]
  • ב: [1, 3 , אחד עשר]
  • ממוין: 1

כעת אנו מסתכלים על הזוג הבא של רכיבים 2 ו-3. 2 קטן יותר ולכן נוסיף אותו לרשימה הממוינת שלנו ונמשיך קדימה לרשימה.

  • ת: [ 2 , 4, 7, 8]
  • ב: [1, 3 , אחד עשר]
  • ממוין: 1

המשך בתהליך זה ונקבל את הרשימה הממוינת של {1, 2, 3, 4, 7, 8, 11}. יכולים להיות שני מקרים מיוחדים.

string.compare c#

מה אם לשתי רשימות המשנה יש אלמנטים זהים - במקרה כזה, נוכל להעביר כל אחת מהרשימה המשנה ולהוסיף את האלמנט לרשימה הממוינת. מבחינה טכנית, אנו יכולים להתקדם הן ברשימת המשנה והן להוסיף את האלמנטים לרשימה הממוינת.

לא נשאר לנו רכיב ברשימה משנה אחת. כשנגמר לנו הרשימה בתת פשוט הוסף את האלמנט של השני אחד אחרי השני.

עלינו לזכור שאנו יכולים למיין את האלמנט בכל סדר. אנו ממיינים את הרשימה הנתונה בסדר עולה אך נוכל למיין בקלות בסדר יורד.

יישום

אלגוריתם מיון המיזוג מיושם על ידי שימוש בגישה מלמעלה למטה. זה יכול להיראות מעט קשה, אז אנו נפרט כל שלב בפרט. כאן, ניישם אלגוריתם זה על שני סוגים של אוספים - רשימת אלמנטים שלמים (בדרך כלל משמשת להצגת מיון) ואובייקט מותאם אישית (תרחיש מעשי ומציאותי יותר).

מערך מיון

הרעיון המרכזי של האלגוריתם הוא לחלק (תת) רשימה לחצאים ולמיין אותם רקורסיבית. אנו ממשיכים בתהליך עד שנגיע לרשימות שיש בהן רק אלמנט אחד. בואו נבין את הפונקציה הבאה לחלוקה -

 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) 

ההתמקדות העיקרית שלנו היא לחלק את הרשימה לחלקי משנה לפני שהמיון יתרחש. אנחנו צריכים לקבל את הערך השלם אז אנחנו משתמשים באופרטור // עבור המדדים שלנו.

בואו נבין את ההליך לעיל על ידי ביצוע השלבים.

  • השלב הראשון הוא ליצור עותקים של רשימות. הרשימה הראשונה מכילה את הרשימות מ [left_index,...,middle] והשני מ [middle+1,?,right_index] .
  • אנו חוצים את שני העותקים של הרשימה באמצעות המצביע, בוחרים בערך הקטן יותר של שני הערכים ומוסיפים אותם לרשימה הממוינת. ברגע שנוסיף את האלמנט לרשימה ונתקדם ברשימה הממוינת בלי קשר.
  • הוסף את הרכיבים הנותרים בעותק השני למערך הממוין.

תן לנו ליישם את מיון המיזוג בתוכנית 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)>

מיון אובייקטים מותאמים אישית

אנו יכולים גם למיין את האובייקטים המותאמים אישית באמצעות ה פִּיתוֹן מעמד. אלגוריתם זה כמעט דומה לאמור לעיל, אך עלינו להפוך אותו למגוון יותר ולהעביר את פונקציית ההשוואה.

ניצור מחלקה מותאמת אישית, רכב ונוסיף לה כמה שדות. אנו עורכים מעט שינויים באלגוריתם שלהלן כדי להפוך אותו למגוון יותר. אנו יכולים לעשות זאת על ידי שימוש בפונקציות למבדה.

בואו נבין את הדוגמה הבאה.

תוכנית פייתון

 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)>

אופטימיזציה

אנחנו יכולים לשפר את הביצועים של אלגוריתם מיון המיזוג. ראשית בואו נבין את ההבדל בין מיון המיזוג מלמעלה למטה ולמטה למעלה. הגישה מלמטה למעלה ממיינת את המרכיבים של רשימות סמוכות באופן איטרטיבי, כאשר הגישה מלמעלה למטה מפרקת את הרשימות לשני החצאים.

מחרוזת ב-c++

הרשימה הנתונה היא [10, 4, 2, 12, 1, 3], במקום לחלק אותה ל-[10], [4], [2], [12], [1], [3] - אנו מחלקים לתוך רשימות המשנה שאולי כבר ממוינות: [10, 4], [2], [1, 12], [3] ועכשיו הם מוכנים למיין אותם.

מיון מיזוג הוא אלגוריתם לא יעיל הן בזמן והן במרחב עבור רשימות המשנה הקטנות יותר. אז, מיון הכנסה הוא אלגוריתם יעיל יותר ממיון המיזוג עבור רשימות המשנה הקטנות יותר.

סיכום

מיון מיזוג הוא אלגוריתם פופולרי ויעיל. זהו אלגוריתם יעיל יותר עבור הרשימות הגדולות. זה לא תלוי בהחלטות מצערות שמובילות לזמני ריצה גרועים.

יש חסרון אחד גדול במיון המיזוג. הוא משתמש בזיכרון הנוסף המשמש לאחסון העותקים הזמניים של רשימות לפני מיזוגן. עם זאת, מיזוג מיזוג נמצא בשימוש נרחב בתוכנה. הביצועים שלו מהירים ומפיקים את התוצאה המצוינת.

דנו בקצרה במושג מיון המיזוג ומיישמים אותו הן ברשימת מספרים שלמים פשוטה והן על אובייקטים מותאמים אישית באמצעות פונקציית למבדה המשמשת להשוואה.