מבוא לחישוב
שיעור 5 – מיונים וחיפוש בינארי
מהו מיון
3 | 1 | 9 | 2 |
1 | 2 | 3 | 9 |
מערך לא ממוין:
מערך ממוין:
מוטיבציה למיון – שיקולי יעילות בחיפוש ערך מסוים
מיון בועות – bubble sort
מיון בועות – דוגמת הרצה
3 | 1 | 9 | 2 |
אם האיבר השמאלי גדול מהימני, נחליף בינהם
1 < 3 ?
החלף
9 < 3 ?
1 | 3 | 9 | 2 |
2 < 9 ?
החלף
1 | 3 | 2 | 9 |
המצב כעת הוא שהאיבר המקסימלי אכן נמצא בסוף, ונתייחס רק למערך שמשמאל לקו
3 < 1 ?
2 < 3 ?
החלף
1 | 2 | 3 | 9 |
המצב כעת הוא ששני האיברים המקסימאלים אכן נמצאים ממוינים בסוף, ונתייחס רק למערך שמשמאל לקו
2 < 1 ?
מיון בועות - הקוד
public static void main(String[] args) {
int arr[] = {3,8,1,4};
for ( ; ; ) {
for ( ; ; ) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
for (i=0 ; i < arr.length ; i++)
System.out.println(arr[i] + “ “);
System.out.println();
}
int[]: arr | |
int: i | ??? |
int: j | ??? |
int: temp | ??? |
int i=arr.length-1
i > 0
i--
int j=0
j < i
j++
int[]: arr | |
int: i | 3 |
int: j | ??? |
int: temp | ??? |
int[]: arr | |
int: i | 3 |
int: j | 0 |
int: temp | ??? |
int[]: arr | |
int: i | 3 |
int: j | 1 |
int: temp | ??? |
int[]: arr | |
int: i | 3 |
int: j | 1 |
int: temp | 8 |
int[]: arr | |
int: i | 3 |
int: j | 2 |
int: temp | 8 |
int[]: arr | |
int: i | 3 |
int: j | 3 |
int: temp | 8 |
int[]: arr | |
int: i | 2 |
int: j | 3 |
int: temp | 8 |
int[]: arr | |
int: i | 2 |
int: j | 0 |
int: temp | 8 |
int[]: arr | |
int: i | 2 |
int: j | 0 |
int: temp | 3 |
int[]: arr | |
int: i | 2 |
int: j | 1 |
int: temp | 3 |
int[]: arr | |
int: i | 2 |
int: j | 2 |
int: temp | 3 |
int[]: arr | |
int: I | 1 |
int: j | 2 |
int: temp | 3 |
int[]: arr | |
int: i | 1 |
int: j | 0 |
int: temp | 3 |
int[]: arr | |
int: i | 1 |
int: j | 1 |
int: temp | 3 |
3 | 8 | 1 | 4 |
3 | 1 | 8 | 4 |
3 | 1 | 4 | 8 |
1 | 3 | 4 | 8 |
0 | 1 | 2 | 3 |
int[]: arr | |
int: i | 0 |
int: j | 1 |
int: temp | 3 |
מיון בועות – �קצת סדר ופונקציות (1)
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void main(String[] args) {()
{
int arr[] = {3,8,1,4};
for (int i=arr.length-1 ; i > 0 ; i-- ) {
for (int j=0 ; j < i ; j++ ) {
if (arr[j] > arr[j+1])
swap(arr, j, j+1);
}
}
for (i=0 ; i < size ; i++)
System.out.print(arr[i] + “ “);
System.out.println();
}
מיון בועות – קצת סדר ופונקציות (2)
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void sortAscending(int arr[]) {
for (int i=arr.length-1 ; i > 0 ; i-- ) {
for (int j=0 ; j < i ; j++ ) {
if (arr[j] > arr[j+1])
swap(arr, j, j+1);
}
}
}
public static void main(String[] args) {
int arr[] = {3,8,1,4};
sortAscending(arr);
for (int i=0 ; i < arr.length ; i++)
System.out.print(arr[i] + “ “);
System.out.println();
}
מיון בועות – מערך ממוין בסדר יורד
כדי למיין את המערך בסדר יורד,
נרצה לפעפע את האיבר הקטן ביותר לסוף.
לכן השינוי היחידי הוא בתנאי לפני ההחלפה
(וכמובן ששם הפונקציה)
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void sortDescending(int arr[]) {
for (int i=arr.length-1 ; i > 0 ; i-- ) {
for (int j=0 ; j < i ; j++ ) {
if (arr[j] < arr[j+1])
swap(arr, j, j+1);
}
}
}
public static void main(String[] args) {
int arr[] = {3,8,1,4};
sortDescending(arr);
for (int i=0 ; i < arr.length ; i++)
System.out.print(arr[i] + “ “);
System.out.println();
}
מיון בועות: אופטימיזציה
public static void sortAscending(int arr[]) {
boolean hasChanged=true;
for (int i=arr.length-1 ; i > 0 && hasChanged ; i-- ) }
hasChanged = false;
for (int j=0 ; j < i ; j++ ) {
if (arr[j] > arr[j+1]) {
swap(arr, j, j+1);
hasChanged = true;
{
{
{
{
התוספת: לאחר איטרציה ללא כל החלפה, ברור כי המערך כבר ממוין ולכן נפסיק
מיון בועות - ניתוח
Selection Sort
8 | 5 | 7 | 3 |
min
3 | 5 | 7 | 8 |
min
min
Selection Sort - הקוד
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void selectionSort(int[] arr) {
for (int i=0 ; i < arr.length ; i++) {
int minIndex = i;
for (int j=i+1 ; j < arr.length ; j++) {
if (arr[j] < arr[minIndex])
minIndex = j;
}
swap(arr, i, minIndex);
}
}
public static void main(String[] args) {
int[] arr = {5,2,8,1,3};
selectionSort(arr);
}
Selection Sort - פונקציות
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
public static void selectionSort(int[] arr) {
int minIndex;
for (int i=0 ; i < arr.length ; i++) {
minIndex = findMinIndex(arr,i);
swap(arr, i, minIndex);
}
public static int findMinIndex(int[] arr, int start) {
int minIndex = start;
for (int j=start+1 ; j < arr.length ; j++) {
if (arr[j] < arr[minIndex])
minIndex = j;
}
return minIndex;
}
מיון בחירה - ניתוח
Insertion Sort
4 | 3 | 5 | 2 |
4 | 3 | 5 | 2 |
3 | 4 | 5 | 2 |
3 | 4 | 5 | 2 |
3 | 4 | 5 | 2 |
3 | 4 | 2 | 5 |
3 | 2 | 4 | 5 |
2 | 3 | 4 | 5 |
Insertion Sort - הקוד
public static void insertionSort(int[] arr) {
for (int i=1 ; i < arr.length ; i++) {
for (int j=i ; j > 0 && arr[j-1] > arr[j] ; j--) {
int temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
}
public static void main(String[] args) {
int[] arr = {7,1,8,2,3,6,4,5};
insertionSort(arr);
}
מיון הכנסה - ניתוח
השוואת זמני ריצה
מיזוג מערכים ממוינים
1 | 0 |
3 | 1 |
2 | 1 | 0 |
4 | 3 | 2 |
4 | 3 | 2 | 1 | 0 |
| | | | |
4 | 3 | 2 | 1 | 0 |
4 | 3 | 3 | 2 | 1 |
מיזוג מערכים ממוינים
רק אחד מהם יקרה...
1 | 0 |
3 | 1 |
2 | 1 | 0 |
4 | 3 | 2 |
4 | 3 | 2 | 1 | 0 |
| | | | |
4 | 3 | 2 | 1 | 0 |
| | | | 1 |
4 | 3 | 2 | 1 | 0 |
| | | 2 | 1 |
4 | 3 | 2 | 1 | 0 |
| | 3 | 2 | 1 |
4 | 3 | 2 | 1 | 0 |
4 | 3 | 3 | 2 | 1 |
מיזוג מערכים ממוינים - הקוד
public static int[] mergeArrays(int arr1[], int arr2[]) {
int[] res = new int[arr1.length + arr2.length];
int i=0, j=0;
while ( i < arr1.length && j < arr2.length ) {
if (arr1[i] <= arr2[j])
res[i+j] = arr1[i++];
else
res[i+j] = arr2[j++];
{
while ( i < arr1.length) // copy rest of arr1
res[i+j] = arr1[i++];
while ( j < arr2.length) // copy rest of arr2
res[i+j] = arr2[j++];
return res;
{
1 | 0 |
3 | 1 |
2 | 1 | 0 |
4 | 3 | 2 |
4 | 3 | 2 | 1 | 0 |
| | | | |
4 | 3 | 2 | 1 | 0 |
| | | | 1 |
4 | 3 | 2 | 1 | 0 |
| | | 2 | 1 |
4 | 3 | 2 | 1 | 0 |
| | 3 | 2 | 1 |
i = 0
j = 0
i = 1
j = 1
i = 2
4 | 3 | 2 | 1 | 0 |
| 3 | 3 | 2 | 1 |
j = 2
4 | 3 | 2 | 1 | 0 |
4 | 3 | 3 | 2 | 1 |
j = 3
arr1:
arr2:
res:
חיפוש בינארי
חיפוש בינארי - הרעיון
3 | 4 | 7 | 14 | 22 | 34 | 37 | 39 | 40 | 44 | 50 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
3 | 4 | 7 | 14 | 22 | 34 | 37 | 39 | 40 | 44 | 50 |
3 | 4 | 7 | 14 | 22 | 34 | 37 | 39 | 40 | 44 | 50 |
חיפוש בינארי – מימוש רקורסיבי
public static int binarySearch(int[] arr, int item, int left, int right) {
if(left>right)
return -1;
int middle = (left+right)/2;
if(arr[middle]==item)
return middle;
if(arr[middle]>item)
return binarySearch(arr,item,left,middle-1);
else
return binarySearch(arr,item,middle+1,right);
}
מימוש איטרטיבי
public static int binarySearch(int a[], int val) {
int low=0,high=a.length-1, middle;
while (low <= high) {
middle = (low + high)/2;
if (val == a[middle])
return middle;
else if (val < a[middle])
high = middle -1;
else
low = middle +1;
}
return -1;
}
public static void main(String[] args) {
int arr[] = {1, 4, 7, 9, 12, 16}, index, value;
value = MyConsole.readInt ("Please enter the value to search: ");
index =
if (index == -1)
System.out.printf("The value %d doesn't exist in the array\n", value);
else
System.out.printf("The value %d exists in index %d\n", value, index);
}
int[]: arr | |
int: index | ?? |
int: value | ?? |
הזיכרון של ה- main
הזיכרון של binarySearch
int[]: a | |
int: val | 4 |
int: low | ?? |
int: high | ?? |
int: middle | ?? |
int[]: a | |
int: val | 4 |
int: low | 0 |
int: high | 5 |
int: middle | ?? |
int[]: a | |
int: val | 4 |
int: low | 0 |
int: high | 5 |
int: middle | 2 |
int[]: a | |
int: val | 4 |
int: low | 0 |
int: high | 1 |
int: middle | 2 |
int[]: a | |
int: val | 4 |
int: low | 0 |
int: high | 1 |
int: middle | 0 |
int[]: a | |
int: val | 4 |
int: low | 1 |
int: high | 1 |
int: middle | 0 |
int[]: a | |
int: val | 4 |
int: low | 1 |
int: high | 1 |
int: middle | 1 |
int[]: arr | |
int: index | ?? |
int: value | 4 |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 7 | 9 | 12 | 16 |
middle
low
high
high
middle
low
middle
int[]: arr | |
int: index | 1 |
int: value | 4 |
binarySearch(arr, value);
מימוש איטרטיבי
int binarySearch(int a[], int val) {
int low=0,high=a.length-1, middle;
while (low <= high) {
middle = (low + high)/2;
if (val == a[middle])
return middle;
else if (val < a[middle])
high = middle -1;
else
low = middle +1;
}
return -1;
}
public static void main(String[] args) {
int arr[] = {1, 4, 7, 9, 12, 16}, index, value;
value = MyConsole.readInt("Please enter the value to search: ")
index =
if (index == -1)
System.out.printf("The value %d doesn't exist in the array\n", value);
else
System.out.printf("The value %d exists in index %d\n", value, index);
}
int[]: arr | |
int: index | ?? |
int: value | ?? |
הזיכרון של ה- main
binarySearch(arr, value);
הזיכרון של binarySearch
int[]: a | |
int: val | 10 |
int: low | ?? |
int: high | ?? |
int: middle | ?? |
int[]: a | |
int: val | 10 |
int: low | 0 |
int: high | 5 |
int: middle | ?? |
int[]: a | |
int: val | 10 |
int: low | 0 |
int: high | 5 |
int: middle | 2 |
int[]: arr | |
int: index | ?? |
int: value | 10 |
0 | 1 | 2 | 3 | 4 | 5 |
1 | 4 | 7 | 9 | 12 | 16 |
middle
low
high
int[]: arr | |
int: index | 1- |
int: value | 10 |
int[]: a | |
int: val | 10 |
int: low | 3 |
int: high | 5 |
int: middle | 2 |
low
int[]: a | |
int: val | 10 |
int: low | 3 |
int: high | 5 |
int: middle | 4 |
middle
int[]: a | |
int: val | 10 |
int: low | 3 |
int: high | 3 |
int: middle | 4 |
high
int[]: a | |
int: val | 10 |
int: low | 3 |
int: high | 3 |
int: middle | 3 |
middle
int[]: a | |
int: val | 10 |
int: low | 4 |
int: high | 3 |
int: middle | 3 |
low
האם אפשר למיין בלי השוואות?
Counting sort
public static void countingSort(int[]arr, int N) {
int index;
N++;
int freq[] = new int[N];
for (int i = 0; i < arr.length; i++)
{
index = arr[i];
freq[index]++;
}
int j = 0;
for (int k=0; k<freq.length; k++)
for (int i=0; i<freq[k]; i++)
arr[j++] = k;
}
Improved counting sort
public static void countingSortV2(int[] arr) {
int min = arr[0], max = arr[0];
for (int i = 1; i < arr.length; i++)
{
if (arr[i]>max)
max = arr[i];
else if (arr[i]<min)
min = arr[i];
}
int freq[] = new int[max-min+1];
for (int i = 0; i < arr.length; i++)
freq[arr[i]-min]++;
int j = 0;
for (int k=0; k<freq.length; k++)
for (int i=0; i<freq[k]; i++)
arr[j++] = k+min;
}
כמה נושאים נוספים
31