Big O notation, common sorting algorithms (with common sorting algorithm codes)

Big O notation and examples

Assuming that checking one element takes 1 millisecond, for 100 elements:
• Binary search: 7 milliseconds (log2(100) is about 7).
• Simple lookup: takes up to 100 milliseconds, about 15 times longer than simple lookup.

Now, if you want to help NASA write a spacecraft landing search algorithm. Need to go from a list of 1 billion elements in 10 seconds, how long does simple search and binary search take?

  Binary search: 30 milliseconds (log21000000000 is about 30).
One way of thinking is: the speed of binary search is about 15 times that of simple search,
then simple search needs 30 × 15 = 450 milliseconds,
which meets the requirements of landing and searching within 10 seconds. Is this correct?

 The answer is wildly wrong! Because binary search and simple search run at different speeds. As the list grows, binary search is much faster than simple search.

To sum up: if the number of executions of an algorithm is T(n), then only the highest order item is kept, and the function f(n) is obtained after ignoring the coefficient of the highest item. At this time, the time complexity of the algorithm is O(f(n) ).

• The speed of an algorithm cannot simply be measured by execution time.
• As the magnitude of the input data increases, the speed-up of the operands is different.
• This is where big O notation comes in.
The reason why it is called big O notation is because there is a big O before the operand .

Time complexity:
The operands of the algorithm to perform operations are discarded from the low-order items, and then all coefficients are removed.
Add an O in front of it, which is big O notation.


 Suppose to find a person in phone book using simple lookup.
If the first person "Zhang San" in the phone book happens to be the object we are looking for, we can find it at one time, without having to look at each entry. Considering that "Zhang San" was found once, is the running time of this algorithm O(n) or O(1)?
In practice simple lookups always run in O(n) time. When looking for Zhang San, he found it once. This is the best case, but the big O notation represents the worst case.
In the worst case, every entry in the phone book must be looked at, corresponding to O(n) running time.


                          

O(1) O(n)

O(n2)

The following lists 5 commonly used Big O running times from fast to slow
• O(log n), also called logarithmic time, such as binary search.
• O(n), also called linear time, such as simple search.
• O(n * log n), such as quicksort, which will be introduced later - a faster sorting algorithm.
• O(n2), as in Selection Sort, which will be introduced later - a slower sorting algorithm.
• O(n!), very slow algorithm.

 

 O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(2n)<O(n!)<O(nn)

The traveling salesman problem in big O notation is O(n!)

np complete problem

 Binary search is much faster than simple search.
O(logn) is faster than O(n), the more elements need to be searched, the faster the former is than the latter.
Algorithm running time is not in seconds.
Algorithm running time is measured from the perspective of its growth rate.
 The running time of the algorithm is expressed in big O notation

Sorting and Sorting Algorithms

Sorting and sorting algorithm
Sorting is the operation of arranging a string of records in increasing or decreasing order according to the size of one or some of the keywords.
Sorting algorithm (Sorting algorithm) is an algorithm that can arrange a string of data in a specific way.

Sorting can make data more structured and facilitate processing. For some information processing tasks, sorted data is easier to use, and sorting is also an important part of many algorithms.
The sorted sequence can be searched by binary method (high efficiency)
Many algorithms need to sort the data used in the calculation
Kruskal algorithm needs to sort the edges in the graph by weight
The best binary tree generation algorithm needs data items to be keyed to sort

Compared to discussing the sorting problem abstractly, we care more about the sorting method of the computer (sorting algorithm)
Some algorithms are intuitive and simple, and the description is simple, but usually inefficient
Some algorithms reflect some essence of the sorting problem more profoundly, Therefore, the efficiency is higher, but it is usually more complicated
 For small collections, the use of complex sorting algorithms may not be worth the loss; for large collections, it is necessary to make full use of various improvement measures as much as possible.

Classification of classic sorting algorithms


Comparative sorting: The relative order between elements is determined by comparison. Since its time complexity cannot break through O(nlogn), it is also called nonlinear time comparison sorting.
Non-comparative sorting: The relative order of elements is not determined by comparison. It can break through the lower bound of comparison-based sorting time and run in linear time, so it is also called linear time non-comparative sorting.

 Related concepts
Stable: If a is originally in front of b, and a=b, a is still in front of b after sorting.
 Unstable: If a is originally in front of b, and a=b, a may appear behind b after sorting.
Time complexity: the total number of operations on sorted data. It reflects the regularity of the number of operations when n changes.
Space complexity: refers to the measurement of the storage space required for the algorithm to execute in the computer, and it is also a function of the data size n.

Bubble sort: The best case is that the data is already ordered, and the complexity is O(n); the worst case is O(), a stable algorithm.

Selection sort: the best case is that the data is already ordered, and the complexity is O(n); the worst case is O(), an unstable algorithm

Direct insertion sorting: the best case is that the data is already ordered, and the complexity is O(n); the worst case is O(), a stable algorithm

Hill sorting: the best case complexity is O(n); the worst case is O(), but the average complexity is smaller than direct insertion, unstable algorithm

Quick sorting: the best case complexity is NlogN, the worst case is O(), quick sorting will unfortunately degenerate into bubble sorting; unstable (such as sequence 5 3 3 4 3 8 9 10 11, now the central element 5 Exchange with 3 (the 5th element, the subscript starts from 1) will disrupt the stability of element 3)

Merge sort : NlogN in all cases, stable algorithm.


Bubble sorting VS selection sorting
Bubble sorting When two adjacent elements have the same size, this step does not need to exchange positions, so bubble sorting is a strict stable sorting algorithm, which does not change the order of the same elements in the sequence. relative positional relationship between them.
Example of selection sorting: sequence 58539. We know that the first selection of the first element "5" will be exchanged with element "3", then the relative order of the two identical elements "5" in the original sequence will change. Therefore, we say that selection sort is not a stable sorting algorithm, it destabilizes during computation.
The time complexity of both algorithms is O(n2)

Hill sorting
 Hill sorting, also known as the descending incremental sorting algorithm, is a more efficient and improved version of insertion sorting. But Hill sort is an unstable sorting algorithm.
Hill sort is an improved method based on the following two properties of insertion sort:
Insertion sort is highly efficient when operating on almost sorted data, that is, it can achieve the efficiency of linear sorting; But
insertion sort is general It is inefficient because the insertion sort can only move the data one bit at a time

Invented by Shell in 1959, the first sorting algorithm that broke through O(n2) is an improved version of simple insertion sort. It differs from insertion sort in that it compares elements that are farther away first. Hill sort is also called shrinking incremental sort.
The basic idea of ​​Hill sorting is: first divide the entire sequence of records to be sorted into several subsequences for direct insertion sorting, and when the records in the entire sequence are "basically ordered", then perform direct insertion sorting on all records in sequence .
How to split the list is the key to Hill sorting - not continuous splitting, but using increment i (sometimes called step size) to select all elements with an interval of i to form a sub-list.

List of sort codes

Hill sort

insertion sort

def insert_sort(li):
    for i in range(1,len(li)):# i 表示摸到牌的下标
        tmp=li[i]
        j=i-1#j指的是手里牌的下标
        while j>=0 and li[j]>tmp:
            li[j+1]=li[j]
            j -=1
        li[j+1]=tmp
        print(li)

li=[3,2,4,1,5,7,9]
print(li)
insert_sort(li)

quick sort

from turtle import left


def partition(li,left,right):
    tmp=li[left]
    while left <right:
        while left <right and li[right]>=tmp:#从右边找比tmp小的数
            right -=1 #往左走一步
        li[left]=li[right] #找到小于的了,替换
        print(li,'right')
        
        while left <right and li[left]<=tmp:#从右边找比tmp小的数
            left+=1 #往左走一步
        li[right]=li[left] #找到小于的了,替换
        print(li,'left')
    li[left]=tmp
    return left

def _quick_sort(li,left,right):
    if left<right:#至少两个元素
        mid=partition(li,left,right)
        _quick_sort(li,left,mid-1)
        _quick_sort(li,mid+1,right)


def quick_sort(li):
     _quick_sort(li,0,len(li)-1)

li=[5,7,6,3,4,1,2,9,8]
print(li)
_quick_sort(li,0,len(li)-1)
print(li)
##时间复杂度是o(nlog n)

Bubble Sort


import random


def bubble_sort(li):
    for i in range(len(li)-1):
        for j in range(len(li)-i-1):
            if li[j]>li[j+1]:
                li[j],li[j+1]=li[j+1],li[j]
                exchange=True
            print(i)
        print(li)
        if not exchange:
            return

li=[8,6,48,4,3,87,7,34,1]
print(li)
bubble_sort(li)

selection sort

def selectionSort(alist):
    for fillslot in range(len(alist)-1, 0, -1):
            positionOfMax = 0
            for location in range(1, fillslot):
                if alist[location] > alist[positionOfMax]:
                    positionOfMax = location

            temp = alist[fillslot] ##最大那个
            alist[fillslot] = alist[positionOfMax]
            alist[positionOfMax] = temp
            print(alist)
    ##时间复杂度为n方,有着两个for循环
    #比冒泡更快
    #长5  fillslot 4 0 -1  location 1 ,5
               #    3 0 -1           1   4
li=[8,6,48,4,3,87,7,34,1]
print(li)
selectionSort(li)    

Guess you like

Origin blog.csdn.net/jcandzero/article/details/126604932