Exchange sort: bubble sort and quick sort

       Exchange refers to swapping the positions of the two elements in the sequence according to the comparison result of the keywords of the two elements in the sequence. Among many sorting algorithms, bubbling and fast sorting belong to exchange sorting.

 

One, bubble sort

1. Basic idea:

Similar to bubbling in water, the smaller ones float up and the larger ones sink. Compare two numbers, the larger number moves backward, and the smaller number moves forward.

2. Algorithm description:

Compare the last element of the sequence with the previous element in pairs. If it is in the reverse order, then exchange the element positions;

According to the above method, perform a pairwise comparison until the first element, then the first element will be the minimum value and the final position;

Compare the remaining sequences according to the above two steps until the sorting is completed.

3. Coding realization:

def swap(s, a, b):
    temp = s[a]
    s[a] = s[b]
    s[b] = temp


def bubblesort(instr):
    n = len(instr)
    for i in range(n-1):
        for j in range(i,n)[::-1]:
            if instr[j-1] > instr[j]:
                swap(instr, j-1, j)


if __name__ == '__main__':
    instr = input().split()
    bubblesort(instr)
    print(''.join(instr))

The above code is the bubble method to achieve sorting. The number of comparisons has nothing to do with the initial state of the sequence. It is always n*(n-1)/2, so the time complexity is O(n^2). A constant number of auxiliary units are used, so the space complexity is O(1).

But if the initial sequence is in order, this comparison will undoubtedly waste resources and time. In order to improve efficiency, a variable flag can be set. If flag is 0, it means that the sequence is an ordered sequence, and there is no need to perform bubble sorting comparison, just exit the loop directly. In this way, in the best case, the number of moves is 0, the number of comparisons is n-1, and the time complexity is O(n). The encoding is as follows:

def swap(s, a, b):
    temp = s[a]
    s[a] = s[b]
    s[b] = temp


def bubblesort(instr):
    n = len(instr)
    for i in range(n-1):
        flag = 0
        for j in range(i,n)[::-1]:
            if instr[j-1] > instr[j]:
                swap(instr, j-1, j)
                flag = 1
        if flag == 0:
            return


if __name__ == '__main__':
    instr = input().split()
    bubblesort(instr)
    print(''.join(instr))

4. Example:

Sort the initial sequence: 5, 4, 3, 2, 1 from small to large

The first sorting process: compare 4 times

The second sorting process: compare 3 times

The third sorting process: compare 2 times

The fourth sorting process: compare 1 time

5. Algorithm analysis:

Each pass of sorting performs n-1 comparisons. After each pass of comparison, an element is placed in the final position, and the number of remaining sorts is n-1. A total of n-1 comparisons are required. In the best case, the number of comparisons is n, the number of moves is 0, and the time complexity is O(n); in the worst case, the number of comparisons is n*(n-1)/2, and the number of moves is 3*n* (n-1)/2, the time complexity is O(n^2). Since no swap operation is performed when the elements are equal, bubble sort is a stable sorting algorithm.

 

Two, quick sort

1. Basic idea: Based on the divide-and-conquer method, the sequence to be sorted is divided into two parts through a sorting. The elements in one part of the sequence are smaller than the reference element, and the elements in the other part of the sequence are larger than the reference element. The two parts of the sequence are sorted until the entire sequence is ordered.

2. Algorithm description:

Select a reference element from the sequence;

Sort the sequence, put all elements smaller than the reference element in the front, and put all elements larger than the reference element in the back, and return the final position of the reference element;

Divide the sequence into two sub-sequences according to the position of the reference element;

Perform the above three steps for each part of the sequence until the sequence is in order.

3. Coding realization:

def partition(instr, low, high):
    p = instr[low]
    while low < high:
        while low < high and instr[high] >= p:
            high = high-1
        instr[low] = instr[high]
        while low < high and instr[low] <= p:
            low = low+1
        instr[high] = instr[low]
    instr[low] = p
    return low


def quickSort(instr, low, high):
    if low < high:
        p = partition(instr,low,high)
        quickSort(instr,low,p-1)
        quickSort(instr,p+1,high)


if __name__ == '__main__':
    instr = input().split()
    quickSort(instr,0,len(instr)-1)
    print(''.join(instr))

4. Example:

       Sort the initial sequence: 3, 5, 1, 6, 2, 7, 4, 9 from small to large, taking the first element as the benchmark

The first partition: divided into two parts

  、

Divide into two parts based on 3, and then divide the two sequences before and after 3 as above until the sequences are in order.

5. Algorithm analysis:

      After each sorting, the reference element will be placed in the final position in the sequence. In the best case, the space capacity is consistent with the maximum depth of the recursive call, which is log2 (n+1). In the worst case, n-1 recursive calls are required, and the stack depth is n-1. Therefore, the maximum The space complexity is O(n) in the bad case, and O(log2 n) in the average case. In the best case, the time complexity is O(n log2 n), and in the worst case, the time complexity is O(n^2). If during the sorting process, two elements are both smaller than the reference element, they will both be moved, and the original order may change, which may cause the final order to be inconsistent with the original order. Therefore, quick sort is an unstable sorting method.

Guess you like

Origin blog.csdn.net/VinWqx/article/details/104858424