SIMPLE Sorting - Computer Science

Download Report

Transcript SIMPLE Sorting - Computer Science

SIMPLE Sorting
• Sorting is a typical operation to put
the elements in an array in order.
• Internal Sorts [for small data sets]
selection
bubble (exchange)
• External Sorts [for large data sets]
Find smallest element, and
put at the head of the list,repeat
with remainder of list
Selection Sort
index (k) sm_index
21 13 9 15 17
0
2
swap 21, 9
9 13 21 15 17
1
1
swap 13, 13
9 13 21 15 17
2
3
swap 21, 15
9 13 15 21 17
3
4
swap 21, 17
9 13 15 17 21
Selection Sort
void sort(double [5]);
void swap(double [5], int, int);
// prototypes
void main(void)
{ int index;
double my_list[ ] = {21, 13, 9, 15, 17};
sort(my_list);
// function call
cout<<"\nThe sorted array is: \n";
for(index=0; index<5; index++)
cout<<'\t'<<my_list[index]<<endl;
}
Selection Sort
void sort(double testArray[5])
{
int n, k, sm_index, moves=0;
double smallest;
for(k=0; k<4; k++)
// size-1 = number of passes
{ smallest=testArray[k];
sm_index=k;
for(n=k+1; n<5; n++) // size = # elem. to look at
if(testArray[n]<smallest)
{
smallest=testArray[n];
sm_index=n;
}
swap(testArray, sm_index, k); // call to swap()
}
}
Bubble Sort
21 13 9 25 17
• Put smaller first
13 21 9 25 17
• Put smaller first
13 9 21 25 17
• No change
13 9 21 25 17
• Put smaller first
Bubble Sort
13 9 21 17 25
• Begin again and
put smaller first
9 13 21 17 25
• No change
9 13 21 17 25
• Put smaller first
9 13 17 21 25
A Bubble Sort Function
void bubble_sort(int array[ ], int length)
{
int j, k, flag=1, temp;
for(j=1; j<=length && flag; j++)
{
flag=0;
// false
for(k=0; k < (length-j); k++)
{
if (array[k+1] > array[k]) // > low to high
{
temp=array[k+1];
// swap
array[k+1]= array[k];
array[k]=temp;
flag=1;
// indicates a swap
} } } }
// has occurred
Insertion sort:
Pick up the cards one at a time. When a
card is picked up put it in the “already
picked up list” in its correct position.
*
G D Z F B E
0 1 2 3 4 5
G D Z F B E
0 1 2 3 4 5
D G Z F B E
0 1 2 3 4 5
D G Z F B E
0 1 2 3 4 5
D F G Z B E
0 1 2 3 4 5
B D F G Z E
0 1 2 3 4 5
B D E F G Z
0 1 2 3 4 5
Index number
InsertionSort( int a[], int n)
{
int I; loc; temp;
for (I = 1; I < n; I++) {
temp = a[I];
loc = I;
GET NEXT ELEMENT TO INSERT
while (loc && (a[loc-1] > temp))
{
a[loc] = a[loc-1];
-- loc;
}
a[loc] = temp;
}
Find its place in list -- keep
moving items down until the
correct locations is found
Insertion Sort
Analysis:
for (I = 1; I < n; I++) {
temp = a[I];
loc = I;
Worst case: O(n2)
1+2+3+4+5….comparisons and moves
BEST CASE?
O(n)
Good for mostly sorted
lists
Average case = O(n2)
while (loc && (a[loc-1] > temp))
{
a[loc] = a[loc-1];
-- loc;
}
a[loc] = temp;
*
Using Pointers for Sorting
In the algorithms looked at the data is
physically re-arranged
Quicksort algorithm
• Split list into two “halves” one greater than
the other
• now split each of these two lists
Elements…………..
j
Less than j
Greater than j
e
<e
s
c
<c
<s
>e
m
g
>c
<g
>s
>g
<m
w
>m
<w
a b c dD e f F g h i j k l mo q s u vwy z
>w
Partition
• Divide the list into two halves: left and right
where the left half is smaller than the right:
• ----> use a “pivot” elements less than the
pivot go left, elements greater than the pivot
go right
left
right
98 32 45 99 101 73 67
left left left
right
67 32 45 99 101 73 67
left
right
67 32 45 99 101 73 99
left right
67 32 45 73 101 73 99
right
left
67 32 45 73 98 101 99
Pivot = 98
int partition(int num[], int left, int right)
{int pivot, temp;
pivot = num[left]; // "capture" the pivot value, which frees up one slot
while (left < right) {
// scan from right to left
while(num[right] >= pivot && left < right) // skip over larger or equal val
right--;
if (right != left)
{ num[left] = num[right]; // move the higher value
left++; }
// scan from left to right
while (num[left] <= pivot && left < right) // skip over smaller or equal val
left++;
if (right != left)
{ num[right] = num[left]; // move lower value into the available slot
right--; }
}
num[left] = pivot; // move pivot into correct position
return left; } // return the pivot index
#include <iostream>
using namespace std;
int partition(int [], int, int); // function prototype
int main()
{
const int NUMEL = 7;
int nums[NUMEL] = {98,32,45,99,101,73,67};
int i, pivot;
pivot = partition(nums, 0, NUMEL-1);
cout << "\nThe returned pivot index is " << pivot;
cout << "\nThe list is now in the order:\n";
for (i = 0; i < NUMEL; i++)
cout << " " <<nums[i];
The pivot index is 4
cout << endl;
the list is now in the order:
return 0;
67 32 45 73 98 101 99
}
*
Quicksort algorithm must call the partition algorithm
until the “list is sorted”, I.e. on each half recursively
until the “halves” are too small
Quicksort algorithm:
pick pivot & partition list
call quicksort(left half)
call quicksort (right half)
Elements…………..
Quicksort(left)
Less than j
j
Q(left/left) e Q(left/rgt)
<e
>e
c
<c
Quicksort(right)
Greater than j
Q(rgt/left) s Q(rgt/rgt)
<s
>s
m
g
>c
<g
>g
<m
w
>m
<w
a b c dD e f F g h i j k l mo q s u vwy z
14 calls to Quicksort
>w
left
right
98 32 45 99 101 73 67
left left left
Pivot = 98
right
67 32 45 99 101 73 67
left
right
67 32 45 99 101 73 99
left right
67 32 45 73 101 73 99
right
left
67 32 45 73 98 101 99
After the partition
with the pivot=98
98 is in its final
position
67 32 45 73 98 101 99
Result of 1st partition
45 32 67 73
32 45
98
99 101
2nd and 3rd partition
4th partition
void quicksort(int num[], int lower, int upper)
{
int i, j, pivot;
pivot = partition(num,lower, upper);
if (lower < pivot)
quicksort(num, lower, pivot - 1);
if (upper > pivot)
quicksort(num, pivot + 1, upper);
return;
}
#include <iostream>
using namespace std;
void quicksort(int [], int, int); // function prototypes
int partition(int [], int, int);
int main()
{
const int NUMEL = 7;
int nums[NUMEL] = {67,32,45,73,98,101,99};
int i;
quicksort(nums, 0, NUMEL-1);
cout << "\nThe sorted list, in ascending order, is:\n";
for (i = 0; i < NUMEL; i++)
cout << " " <<nums[i];
cout << endl;
return 0;
}
Quicksort(nums, 0, 6)
pivot (after partition = 2) 67 32 45 73 98 101 99
45 32 67 73 98 101 99
Quicksort(nums, 0, 1)
45 32
pivot (after partition = 1) 32 45
Quicksort(nums, 0, 0)
32
pivot (after partition = 0)
73 98 101 99
Quicksort(nums, 3,6)
pivot (after partition = 3)
98 101 99
101 99
99 101
99
Quicksort(nums, 4,6)
pivot (after partition = 4)
Quicksort(nums, 5,6)
pivot (after partition = 6)
Quicksort(nums, 5,5)
pivot (after partition = 5)
IN CLASS Assignment:
Given the list of numbers below, write out the
steps for the quicksort algorithm:
12 14
3 6 56
2 10 25 89 8
12
14
3
8 10
6
56
3 6 2
Piv=8
2
6
12 56 25 89 14
Piv=56
3
8
10
Piv=2
2
2 10 25 89 8
12 14 25 56 89
Piv=14
6
3 8
10
12 14 25 56 89
Piv=6
2
3
6
8
10
12 14 25 56 89
Piv=12
Analysis of Quicksort:
void quicksort(int num[], int lower, int upper)
{
int i, j, pivot;
pivot = partition(num,lower, upper);
if (lower < pivot)
quicksort(num, lower, pivot - 1);
if (upper > pivot)
quicksort(num, pivot + 1, upper);
Takes O(upper-lower) since
every element must be compared
to the pivot
Best case time:
Time(Quicksort(n)) = Partition(n) + Quicksort(n/2)+Quicksort(n/2)
O(n)
Partition(n/2) + Quicksort(n/4) + Quicksort(n/4) +
Partition(n/2) + Quicksort(n/4) + Quicksort(n/4)
= O(n) + 2*O(n/2) + 4*(Quicksort(n/4) …
= O(n) + O(n) + O(n)
Log(n) times…..
= O(nlogn)
Worst case time:
1
1
1
1
1
1
1
1
1
1
2
2
2
2
2
2
2
2
2
2
3
3
3
3
3
3
3
3
3
3
4
4
4
4
4
4
4
4
4
4
5
5
5
5
5
5
5
5
5
5
6
6
6
6
6
6
6
6
6
6
7
7
7
7
7
7
7
7
7
7
8
8
8
8
8
8
8
8
8
8
9
9
9
9
9
9
9
9
9
9
10
N times
10
10
10
10
10
10
10
10
10
= O(n2)