我要好offer之 排序算法大总结

1. 插入排序

(1) 直接插入排序

void StraightInsertionSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    for (int i = 1; i < num.size(); ++i) {
        int tmp = num.at(i);
        int j = i - 1;
        for (; j >= 0 && num.at(j) > tmp; --j) {
            num.at(j + 1) = num.at(j); 
        }
        num.at(j + 1) = tmp;
    }
}

(2) 折半插入排序

void BinaryInsertionSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    for (int i = 1; i < num.size(); ++i) {
        int tmp = num.at(i);
        int first = 0;   // 最终的first值即为插入位置
        int last = i - 1;
        while (first <= last) {
            int mid = first + (last - first) / 2;
            if (num.at(mid) < tmp) {
                first = mid + 1;
            } else if (num.at(mid) > tmp) {
                last = mid - 1;
            } else {
                first = mid;
                break;
            }
        }
        
        for (int t = i - 1; t >= first; --t) {
            num.at(t + 1) = num.at(t);
        }
        num.at(first) = tmp;
    }
}

 

2. 希尔排序

void ShellSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    for (int gap = num.size() / 2; gap > 0; gap /= 2) {
        for (int i = gap; i < num.size(); ++i) {
            for (int j = i - gap; j >= 0 && num.at(j) > num.at(j + gap); j -= gap) {
                std::swap(num.at(j), num.at(j + gap));
            }
        }
    }
}

 

3. 冒泡排序

void BubbleSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    for (int i = 0; i < num.size(); ++i) {
        for (int j = 0; j < num.size() - i - 1; ++j) {
            if (num.at(j) > num.at(j + 1)) {
                std::swap(num.at(j), num.at(j + 1));
            }
        }
    }
}

 

4. 快速排序

(1) 递归版

// 划分
int Partition(std::vector<int>& num, int first, int last) {
    assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last);
    int mid = first + (last - first) / 2;
    std::swap(num.at(first), num.at(mid));
    int pos = first;
    for (int i = first; i <= last; ++i) {
        if (num.at(i) < num.at(first)) {
            std::swap(num.at(++pos), num.at(i));
        }
    }
    std::swap(num.at(first), num.at(pos));
    return pos;
}

// 快速排序
void quickSort(std::vector<int>& num, int first, int last) {
    if (first < last) {
        int pivotPos = Partition(num, first, last);
        quickSort(num, first, pivotPos - 1);
        quickSort(num, pivotPos + 1, last);
    }
}

void QuickSort(std::vector<int>& num) {
    quickSort(num, 0, num.size() - 1);
}

 

(2) 非递归版

int Partition(std::vector<int>& num, int first, int last) {
    assert(first >= 0 && first < num.size() && last >= 0 && last < num.size() && first <= last);
    int mid = first + (last - first) / 2;
    std::swap(num.at(first), num.at(mid));
    int pos = first;
    for (int i = first; i <= last; ++i) {
        if (num.at(i) < num.at(first)) {
            std::swap(num.at(++pos), num.at(i));
        }
    }
    std::swap(num.at(first), num.at(pos));
    return pos;
}

void QuickSort(std::vector<int>& num, int first, int last) {
    if (first < last) {
        std::stack<int> stk;
        int pivotPos = Partition(num, first, last);
        if (first < pivotPos - 1) {
            stk.push(first);
            stk.push(pivotPos - 1);
        }
        if (last > pivotPos + 1) {
            stk.push(pivotPos + 1);
            stk.push(last);
        }
        while (!stk.empty()) {
            int right = stk.top();
            stk.pop();
            int left = stk.top();
            stk.pop();
            pivotPos = Partition(num, left, right);
            if (left < pivotPos - 1) {
                stk.push(left);
                stk.push(pivotPos - 1);
            }
            if (right > pivotPos + 1) {
                stk.push(pivotPos + 1);
                stk.push(right);
            }
        }
    }
}

 

5. 简单选择排序

void SimpleSelectSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    for (int i = 0; i < num.size(); ++i) {
        for (int j = i + 1; j < num.size(); ++j) {
            if (num.at(j) < num.at(i)) {
                std::swap(num.at(i), num.at(j));
            }
        }
    }
}

 

6. 堆排序

堆的有关操作

// 堆调整,注意结点编号kth从1开始
void HeapAdjust(std::vector<int>& num, int kth, int vecSize) {
    int left = 2 * kth;
    int right = 2 * kth + 1;
    int largest = INT_MIN;
    if (left <= vecSize && num.at(left - 1) > num.at(kth - 1)) {
        largest = left;
    } else {
        largest = kth;
    }
    
    if (right <= vecSize && num.at(right - 1) > num.at(largest - 1)) {
        largest = right;
    }
    if (largest != kth) {
        std::swap(num.at(kth - 1), num.at(largest - 1));
        HeapAdjust(num, largest, vecSize);
    }
}

// 建堆
void BuildHeap(std::vector<int>& num) {
    for (int i = num.size() / 2; i >= 0; --i) {
        HeapAdjust(num, i + 1, num.size());
    }
}

// 堆排序
void HeapSort(std::vector<int>& num) {
    BuildHeap(num);
    int vecSize = num.size();
    while (vecSize > 1) {
        std::swap(num.at(0), num.at(vecSize - 1));
        --vecSize;
        HeapAdjust(num, 1, vecSize);
    }
}

 

7. 归并排序

void merge(std::vector<int>& num, int first, int mid, int last) {
    std::vector<int> tmp(last - first + 1, 0);
    int i = first;
    int j = mid + 1;
    int idx = 0;
    while (i <= mid && j <= last) {
        if (num.at(i) <= num.at(j)) {
            tmp.at(idx++) = num.at(i++);
        } else {
            tmp.at(idx++) = num.at(j++);
        }
    }
    while (i <= mid) {
        tmp.at(idx++) = num.at(i++);
    }
    while (j <= last) {
        tmp.at(idx++) = num.at(j++);
    }
    for (int i = first; i <= last; ++i) {
        num.at(i) = tmp.at(i - first);
    }
}

void MergeSort(std::vector<int>& num, int first, int last) {
    if (first < last) {
        int mid = first + (last -first) / 2;
        MergeSort(num, first, mid);
        MergeSort(num, mid + 1, last);
        merge(num, first, mid, last);
    }
}

 

8. 计数排序

void CountSort(std::vector<int>& num) {
    if (num.size() == 0 || num.size() == 1) return;
    int minVal = *(std::min_element(num.begin(), num.end()));
    int maxVal = *(std::max_element(num.begin(), num.end()));
    int valRange = maxVal - minVal + 1;
    std::vector<int> count(valRange, 0);
    for (int i = 0; i < num.size(); ++i) {
        count.at(num.at(i) - minVal)++;
    }
    
    for (int i = 1; i < count.size(); ++i) {
        count.at(i) = count.at(i) + count.at(i - 1);
    }
    
    std::vector<int> tmp(num);
    
    for (int i = tmp.size() - 1; i >= 0; --i) {
        int lessNum = count.at(tmp.at(i) - minVal);
        num.at(lessNum - 1) = tmp.at(i);
        count.at(tmp.at(i) - minVal)--;
    }
}

 

小结: 

排序算法总结-维基百科

 

 

posted @ 2014-08-15 21:38  skyline09  阅读(364)  评论(0编辑  收藏  举报