Sorting algorithm commonly used C ++

Here Insert Picture Description

Bubble Sort

Bubble sort is a relatively simple O (n2) sorting algorithm level, the idea is relatively close to the value one by one, and then swap positions, as in the water bubbles, always bring maximum or minimum exchange to the top .

/**
 * 冒泡排序
 */
template<typename T>
void bubble_sort(T arr[], int length)
{
    for (int i=0; i< length-1; i++){

        for(int j=0; j< length-1-i; j++){
            if (arr[j] > arr[j+1]){
                swap(arr[j], arr[j+1]);
            }
        }

    }
}

Selection Sort

Select the sort of level algorithm is O (n2), the idea is to start from the first index, and the rest were compared, and the index value of at most record, followed by relatively down. If the current index and the initial index different, you need to exchange value. At this time, the smallest element in the front row. And so on.

/**
 *选择排序
 */
template<typename T>
void select_sort(T arr[], int length){
    for (int i=0; i<length-1; i++){
        int minIndex = i;
        for(int j = i+1; j<length; j++){
            if(arr[minIndex] > arr[j]){
                minIndex = j;
            }
        }
        if(minIndex!=i){
            swap(arr[i], arr[minIndex]);
        }
    }
}

Insertion Sort

Insertion sort, and assume that the data is complete arrangement, then the current value of the need to sequentially compare its front, until it encounters position is greater than, and inserted therein. When the general implementation can choose to turn swap positions can also be assigned.
Specific achieve the following:

/**
 * 插入排序  交换数值
 */
template <typename T>
void insert_sort(T arr[], int length){
    for(int i=0; i< length -1; i++){
        for (int j = i+1; j>0 && (arr[j-1] > arr[j]); j--){
            //if (arr[j-1] > arr[j]){
                swap(arr[j-1], arr[j]);
           // }
        }
    }
}

It can be optimized, does not need to be exchanged every time proximity, this is bound to be a waste of space and time, can be assigned to operate

template <typename T>
void insert_sort2(T arr[], int length){
    for(int i=1; i< length; i++){
        T val = arr[i]; // 当前元素的值
        int j;
        for(j=i; j>0 && val < arr[j-1]; j--){
            arr[j] = arr[j-1]; // 向前移动
        }
        if(j!=i){
            arr[j] = val;
        }
    }
}

Can also be seen from the code, an insertion sort to most properly arranged sequence is very fast.

Shell sort

Insertion sort step is the use of a sort, Shell sort and insertion sort on the basis of the first use of large step size, only step up to 1, so that the whole thought substantially ordered sequence.

/**
 *希尔排序
 *
 */
template <typename T>
void shell_sort(T arr[], int length){
    int gap = 1;
    while (gap < length / 3) {
       gap = 3 * gap + 1;
    }
    cout << "gap = " << gap << endl;
    // 间隔Gap 进行插入排序
    while (gap>0) {
    	// 这里其实就是插入排序,只是以gap为间隔进行排序
        for(int i = 0; i <length; i += gap){
            for(int j= i + gap; j > 0 && (arr[j] < arr[j-gap]); j -= gap){
                 swap(arr[j], arr[j-gap]);
            }
        }
        gap = gap/3;
    }
}

Merge sort

We are constantly put an array, divided into two halves, but in the end can not be divided, and then up a sort-merge, typical of recursive thinking

/**
 *归并排序
 *  分为左右,然后排序,然后合并 开辟临时内存空间
 */
template <typename T>
void merge_sort(T arr[], int length){
    __merge_sort(arr, 0, length-1);
}

template <typename T>
void __merge_sort(T arr[], int l, int r){
    if (l >=r){
        return;
    }

    int mid = l + (r-l) /2;  //(r+l)/2;
    __merge_sort(arr, l, mid);
    __merge_sort(arr, mid+1, r);

    // [l, mid] [mid+1, r]
    T * aux = new T[r-l+1];
    for(int i=l; i<=r; i++){
        aux[i-l] = arr[i];
    }

    int i = l, j = mid+1;
    for(int k = l; k <= r; k++){
        if (i > mid){
            arr[k] = aux[j-l]; // 复制剩下的右半边
            j++;
        }else if (j > r){
            arr[k] = aux[i-l]; // 复制剩下的左半边
            i++;
        }else if(aux[i-l] < aux[j-l]){
            arr[k] = aux[i-l]; // 复制左半边
            i++;
        }
        else{
            arr[k] = aux[j-l]; // 复制右半边
            j++;
        }
    }

    delete[] aux;

}

Quick Sort

Thought quicksort is divide and rule, preferred to choose a basic value, then less than in the left array half, is greater than in the right half of the middle part is the basic value of the basic value, followed by the left of the basic values ​​of recursion, on the right half also recursive.

/**
 *快速排序  需要选择基准的数据,默认第一个,也可以随机选择
 */
template<typename T>
void quick_sort(T arr[], int length){
    __quick_sort(arr, 0, length-1);
}

template<typename T>
void __quick_sort(T arr[], int l, int r){
    if(l >= r)
    {
        return;
    }
    int index = __partition(arr, l, r);
    __quick_sort(arr, l, index-1);
    __quick_sort(arr, index+1, r);

}
template <typename T>
int __partition(T arr[], int l, int r){
    // 从两端向内
    //int index = rand()%(r-l+1)+l;
    //swap(arr[l], arr[index]);
    T v = arr[l]; // 选择第一个为基准值,也可随机选择,然后交换再进行
    int i = l + 1, j = r;

    while( true ){
        // 注意这里的边界, arr[i] < v, 不能是arr[i] <= v
        while( i <= r && arr[i] < v )
            i ++;

        // 注意这里的边界, arr[j] > v, 不能是arr[j] >= v
        while( j >= l+1 && arr[j] > v )
            j --;

        if( i > j )
            break;

        swap( arr[i] , arr[j] );
        // 注意这里的交换完,需要都向前移动一位
        i ++;
        j --;
    }

    swap(arr[l], arr[j]);
    return j;


Heapsort

We must first understand what is heap that is actually a binary tree, divided into large and small pushing pushing, small to large sort, usually a small push. Small top stack value is less than the value of the parent node of the two child nodes. Specific can see the definition of the heap, there is not much to say.

/**
 * 对元素组的堆排序
 */
template<typename T>
void heap_sort(T arr[], int length){
	// 构建堆
    for(int i = (length-1)/2; i >= 0; i--){
        __siftDown(arr, length, i);
    }

    for(int i = length-1; i >= 0; i--){
        swap(arr[0], arr[i]);
        __siftDown(arr, i, 0);
    }
}
template<typename T>
void __siftDown(T arr[], int length, int k){

    while ( 2*k+1 < length) {

        int i = 2*k + 1;
        if(i+1<length && arr[i] < arr[i+1]){
            i ++;
        }

        if(arr[k] >= arr[i])
            break;

        swap(arr[k], arr[i]);

        k = i;
    }
}

Reference: https://www.runoob.com/w3cnote/ten-sorting-algorithm.html

Published 24 original articles · won praise 4 · Views 8252

Guess you like

Origin blog.csdn.net/zhaitianyong/article/details/104815099