When it comes to sorting and efficiency, often the algorithm used as well as the size of elements will determine the efficiency for sorting or searching. Nowadays, various algorithms were designed to facilitate the efficiency when running a program. For instance Timsort was an algorithm implemented into python as a built-in sort. As we have analyzed during the lab this week, Timsort was most efficient sorting algorithm when compared with insertion, bubble, merge, and quick sort. As a hybrid algorithm of merge sort and insertion sort, Timsort does approaches runtime of a merge sort when list of elements need to be sorted becomes large at worst case scenario with performance of O(nlog n). This is same as performance of merge sort.
In the lab, the data we collected data that shows selection sort
and bubble sort seems to have the worst run time efficiency with performance of
O(n^2) at worst case, since they have to compare approximately elements n^2
times to sort the list in correct order.
Run time efficiency for quick sort depends on how the pivots
were chosen each time, where predictable pivot points chosen may results in
O(n^2) performance. As shown during the lectures, my prof mentioned choosing
random pivots during quick sort can help avoid possible worst run time of
O(n^2). Similarly, a sorted list of elements give insertion sort run time of
O(n), and reverse sorted elements gives run time of O(n^2). Due to the numbers
of comparisons required to sort an element in the correct position in elements
that are already sorted, insertion sort have this characteristic. From time to
time, the order of the elements to be sorted will affect the run time of an
algorithm as demonstrated by quick sort and insertion sort.
Often recursive call may call on another recursive call that
may have already been evaluated. To avoid redundancy of recursive calls,
returned values can be stored such as in a list in a higher level scope, so repeated
calls can refer to the stored value rather than making redundant evaluations. For
example, the Fibonacci function example we discussed earlier can apply such strategy to reduce the function run time. Similar strategy was used in binary search tree to search for, or inserting a
value in the tree. Since left branch
only have nodes smaller than current node value, and right branch only have
nodes bigger than current node value, binary tree will search exactly like
binary search algorithm. This means each step, the amount of element current looking at is halved
each time.
Sorting depends on the efficiency of the algorithm from time
to time. Through my experiences of making both efficient and inefficient codes
in the past, I become aware of the fact that efficiency will affect the
overall performance of a program, and how data were organized together will affect the
efficiency as a result.