Bubble sort
Contents
1.introduction
2.algorithm comparison
3.References
introduction
1.bubble sort
Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that repeatedly steps through the list to be sorted, compares each pair of adjacent items and swaps them if they are in the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list is sorted. The algorithm, which is a comparison sort, is named for the way smaller or larger elements "bubble" to the top of the list. Although the algorithm is simple, it is too slow and impractical for most problems even when compared to insertion sort.[2] Bubble sort can be practical if the input is in mostly sorted order with some out-of-order elements nearly in position.
-from Wikipedia
Profiling
Data structure | Array |
---|---|
Worst-case | О(n2) comparisons |
performance | О(n2) swaps |
Best-case | О(n) comparisons |
performance | О(1) swaps |
Average | О(n2) comparisons |
performance | О(n2) swaps |
Worst-case space complexity | О(1) auxiliary |
Algorithm demo
Detailed steps
Code snippets
Define an array to hold the initial array
private int[] array;
private int length;
public Bobsort(int[] array){
this.array = array;
this.length = array.length;
}
Function that implements bubble sorting
public void bobSort(){
for(int i=0;i<length-1;i++){
for(int j=0;j<length-1-i;j++){
if(array[j]>array[j+1]){
int temp = array[j+1];
array[j+1] = array[j];
array[j] = temp;
}
}
}
}
Output result
public void print(){
for(int i : array){
System.out.print(i+" ");
}
System.out.println();
}
Generate random data, output array before and after sorting, get time for subsequent comparison
public static void main(String[] args){
int array[]=new int[1000000];
for(int i=0;i<1000;i++)
{
array[i]=(int) ( Math.random() *500 );
}
Bobsort bobSort = new Bobsort(array);
System.out.println("排序前的数据为:");
bobSort.print();
System.out.println("排序前的时间为:");
System.out.println(new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()));
bobSort.bobSort();
System.out.println("排序后的数据为:");
bobSort.print();
System.out.println("排序后的时间为:");
System.out.println(new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()));
}
Result display for 1000 random number from 1-1000
Complexity analysis
Average and worst case complexity of bubble sort is O(n2). Also, it makes O(n2) swaps in the worst case. Bubble sort is adaptive. It means that for almost sorted array it gives O(n) estimation. Avoid implementations, which don't check if the array is already sorted on every step (any swaps made). This check is necessary, in order to preserve adaptive property.
One more problem of bubble sort is that its running time badly depends on the initial order of the elements. Big elements (rabbits) go up fast, while small ones (turtles) go down very slow.
Although bubble sort is one of the simplest sorting algorithms to understand and implement, itsO(n2)complexity means that its efficiency decreases dramatically on lists of more than a small number of elements. Even among simple O(n2) sorting algorithms, algorithms like Insertion sort are usually considerably more efficient.
Due to its simplicity, bubble sort is often used to introduce the concept of an algorithm, or a sorting algorithm, to introductory computer science students. However, some researchers such as Owen Astrachan have gone to great lengths to disparage bubble sort and its continued popularity in computer science education, recommending that it no longer even be taught.
In computer graphics bubble sort is popular for its capability to detect a very small error (like swap of just two elements) in almost-sorted arrays and fix it with just linear complexity (2n). For example, it is used in a polygon filling algorithm, where bounding lines are sorted by their x coordinate at a specific scan line (a line parallel to the x axis) and with incrementing y their order changes (two elements are swapped) only at intersections of two lines. Bubble sort is a stable sort algorithm, like insertion sort.
2.merge sort
Like quick-sort, Merge Sort is a divide-and-conquer-introduction algorithm. It divides input array in two halves, calls itself for the two halves and then merges the two sorted halves. The merge() function is used for merging two halves. The merge(arr, l, m, r) is key process that assumes that arr[l..m] and arr[m+1..r] are sorted and merges the two sorted sub-arrays into one. See following C implementation for details.
-from GeeksforGeeks
Profiling
Data structure | Array |
---|---|
Worst-case | O(n log n) |
performance | n log n - n - 1(in my opinion) |
Best-case | O(n log n) typical |
performance | O(n) natural variant |
Average | O(n log n) |
performance | О(n2) swaps |
Worst-case space complexity | auxiliary, O(1) auxiliary with linked lists |
Algorithm demo
Detailed steps
Code snippets
Initial array, recursive to no longer divisible
public static void mergeSort(int[] data) {
sort(data, 0, data.length - 1);
}
public static void sort(int[] data, int left, int right) {
if (left >= right)
return;
int center = (left + right) / 2;
sort(data, left, center);
sort(data, center + 1, right);
merge(data, left, center, right);
}
Function that implements merge sorting
public static void merge(int[] data, int left, int center, int right) {
int[] tmpArr = new int[data.length];
int mid = center + 1;
int third = left;
int tmp = left;
while (left <= center && mid <= right) {
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
Generate random data, output array before and after sorting, get time for subsequent comparison
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int array[]=new int[1000];
for(int i=0;i<1000;i++)
{
array[i]=(int) ( Math.random()*500 );
}
System.out.println("排序前的数据为:");
print(array);
System.out.println("排序前的时间为:");
System.out.println(new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()));
mergeSort(array);
System.out.println("排序后的数据为:");
print(array);
System.out.println("排序后的时间为:");
System.out.println(new SimpleDateFormat("HH:mm:ss:SSS").format(new Date()));
}
}
Result display for 1000 random number from 1-1000
Analyzing Merge Sort
For simplicity, assume that n is a power of 2 so that each divide step yields two subproblems, both of size exactly n/2.
The base case occurs when n = 1.
When n ≥ 2, time for merge sort steps:
Divide: Just compute q as the average of p and r, which takes constant time i.e. Θ(1).
Conquer: Recursively solve 2 subproblems, each of size n/2, which is 2T(n/2).
Combine: MERGE on an n-element subarray takes Θ(n) time.
Summed together they give a function that is linear in n, which is Θ(n). Therefore, the recurrence for merge sort running time is
Recursion Tree
We can understand how to solve the merge-sort recurrence without the master theorem. There is a drawing of recursion tree on page 35 in CLRS, which shows successive expansions of the recurrence.
The following figure (Figure 2.5b in CLRS) shows that for the original problem, we have a cost of cn, plus the two subproblems, each costing T (n/2).
The following figure (Figure 2.5c in CLRS) shows that for each of the size-n/2 subproblems, we have a cost of cn/2, plus two subproblems, each costing T (n/4).
The following figure (Figure: 2.5d in CLRS) tells to continue expanding until the problem sizes get down to 1.
In the above recursion tree, each level has cost cn.
The top level has cost cn.
The next level down has 2 subproblems, each contributing cost cn/2.
The next level has 4 subproblems, each contributing cost cn/4.
Each time we go down one level, the number of subproblems doubles but the cost per subproblem halves. Therefore, cost per level stays the same.
The height of this recursion tree is lg n and there are lg n + 1 levels.
algorithm comparison
bubble sort
Clearly, the graph shows the n2 nature of the bubble sort.
In this algorithm the number of comparison is irrespective of data set i.e., input whether best or worst.
merge sort
The inductive hypothesis is that a tree for a problem size of 2i has lg 2i + 1 = i +1 levels. Because we assume that the problem size is a power of 2, the next problem size up after 2i is 2i + 1. A tree for a problem size of 2i + 1 has one more level than the size-2i tree implying i + 2 levels. Since lg 2i + 1 = i + 2, we are done with the inductive argument.
Total cost is sum of costs at each level of the tree. Since we have lg n +1 levels, each costing cn, the total cost is cn lg n + cn.Ignore low-order term of cn and constant c, and we have,Θ(n lg n) which is the desired result.
memory requirement
As for bubble sort,it doesnt need any extra memory,and for merge sort if a temporary array is declared for each recursive call to merge, logn temporary arrays may be active at any one time, which is fatal to small memory machines. On the other hand, if merge dynamically allocates and releases the minimum amount of temporary space, the time occupied by malloc(Request the system to allocate memory space of specified size bytes) will be much longer. Since merge is on the last row of m sort, you can create the temporary array in merge sort. Therefore, only one temporary array activity is needed at any time, and any part of the temporary array can be used. We will use the same part as the input array Array. In this case, the space occupied by the algorithm is n, n is the number of array elements to be sorted.