您的位置:首页 > 编程语言 > C语言/C++

常用的8种排序算法总结

2017-03-22 11:18 281 查看

常用的8种排序算法总结

平台:VS2013

编程语言: c/c++

1. 桶排序

简单桶排序算法的核心思想为将每一个数字作为桶的编号,如果在序列中有该数字便放入该桶中,因此算法的时间复杂度为O(n), 但空间复杂度很大,浪费了很多空间。具体代码如下:

//c/c++
//bucketSort
void    bucketSort(vector<int>& vNum){
map<int, int> mNum;//使用map作为桶可以有效减少空间的浪费
for (auto i : vNum)
mNum[i]++;
vector<int> vTmp;
for (auto it = mNum.begin(); it != mNum.end(); ++it){
while (it->second--){
vTmp.push_back(it->first);
}
}
vNum = vTmp;
}


2. 冒泡排序

冒泡排序的核心思想为遍历整个数组,将一个数字逐次地与整个序列进行比较,如果发现该数小于(或大于)序列中的数,便对两数字进行交换,该数遍历完毕,则进行下一个数字的遍历,直到将所有的数字遍历完毕。因此其时间复杂度为O(n^2),空间复杂度为O(n),代码如下:

//c/c++
//bubble sort
void    bubbleSort(vector<int>& vNum){
for (int i = 0; i < vNum.size(); ++i){
for (int j = 1 + i; j < vNum.size(); ++j){
if (vNum[j] < vNum[i]){
int tmp = vNum[i];
vNum[i] = vNum[j];
vNum[j] = tmp;
}
}
}
}


3. 选择排序

选择的排序的中心思想为依次选择序列中的数字作为key,然后遍历剩下的数字,如果发现该数小于key便记录下该数的位置,遍历完毕后,将key与最小位置的数进行交换。则其时间复杂度为O(n^2),空间复杂度为O(n),其源码如下

//c/c++
//choose sort
void    chooseSort(vector<int>& vNum){
for (int i = 0; i < vNum.size(); ++i){
int key = i;
for (int j = i + 1; j < vNum.size(); ++j){
if (vNum[j] < vNum[key])
key = j;
}
if (key != i){
int tmp = vNum[i];
vNum[i] = vNum[key];
vNum[key] = tmp;
}
}
}


4. 直接插入排序

直接插入排序的核心思想为在序列中选择一个数,直接与其前面的一个个进行比较,如小于前面的则将原序列中的数字后移一位,直到最后将所有的数遍历完成,直接插入排序的时间复杂度为O(n^2),其空间复杂度为O(N),其源码如下

//c/c++
//insert sort
void    insertSort(vector<int>& vNum){
for (int i = 1; i < vNum.size(); ++i){
int key = vNum.at(i);
int j = i - 1;
for (j = i - 1; j >= 0; --j){
if (vNum.at(j) > key){
vNum[j + 1] = vNum[j];
}
else break;
}
vNum[j + 1] = key;
}
}


5. 希尔排序

希尔排序属于插入排序算法,直接插入算法的间距为1,而希尔排序的算法间距时变化的,希尔排序的中心思想,取一个间距k, 一般取 k = n/3,其中n为序列长度。然后在序列中进行循环,每一次循环更新一次k=k/3;直到k为0。则其时间复杂度为O(N^1.5), 要比以上的好一些。其代码如下

c/c++
//shell sort
void    shellSort(vector<int>& vNum){
int k = (vNum.size() / 3) + 1;
while (k){
for (int i = k; i < vNum.size(); ++i){
int key = vNum.at(i);
int j = i - k;
for (j = i - k; j >= 0; j -= k){
if (key < vNum.at(j))
vNum[j + k] = vNum[j];
else break;
}
vNum[j + k] = key;
}
k /= 3;
}
}


6. 快速排序

快速排序的核心思想为:二分法。先选定一个数字作为key,然后遍历序列,将大于key的放在key右边,小于key的放在key左面,然后分别对左右两边序列进行相应的处理算法,直到每个序列中只有一个数字。其时间复杂度为O(NlogN)。其源码如下

//c/c++
//quick sort: [low, high]
void    quickSort(vector<int>& vNum, int low, int high){
if (low >= high) return;
else{
int mid = low;
int key = vNum.at(low);
int left = low + 1;
int right = high;

while (left < right){
if (vNum[left] > key && vNum[right] < key){
int t = vNum[left];
vNum[left] = vNum[right];
vNum[right] = t;
}
else{
if (vNum[left] <= key) ++left;
if (vNum[right] >= key) --right;
}
}
if (vNum[left] < key){
int t = vNum[left];
vNum[left] = key;
vNum[low] = t;
mid = left;
}
else{
int t = vNum[left - 1];
vNum[left - 1] = key;
vNum[low] = t;
mid = left - 1;
}

quickSort(vNum, low, mid - 1);
quickSort(vNum, mid + 1, high);
}
}


7. 归并排序

归并排序的核心思想为不断将序列二分往下递归,然后在不断将两个序列进行比较往上递归。其时间复杂度为O(NlonN),其源码如下

//merge sort:[low, high]
void merge(vector<int>& vNum, int low, int mid, int high){
int i = low;
int j = mid + 1;
vector<int> vNumTmp;
while (i <= mid && j <= high){
if (vNum[i] < vNum[j])vNumTmp.push_back(vNum[i++]);
else vNumTmp.push_back(vNum[j++]);
}
/////////////////////////////////////////////////
while (i <= mid) vNumTmp.push_back(vNum[i++]);
while (j <= high)vNumTmp.push_back(vNum[j++]);
///////////////////////////////////////////////
for (int i = 0; i < vNumTmp.size(); ++i)
vNum[i + low] = vNumTmp[i];

}
void mergeSort(vector<int >& vNum, int low, int high){
if (low >= high) return;
else{
int mid = (low + high) / 2;
mergeSort(vNum, low, mid);
mergeSort(vNum, mid + 1, high);
merge(vNum, low, mid, high);
}
}


8. 堆排序

堆排序其实就是在完全二叉树的基础上,进行求解最大数。每一次求解后,在重新寻找,其时间按复杂度为O(NlonN)。其源码如下

//heap sort
int maxHeap(vector<int>& vNum){
int l = log2(vNum.size());
for (int i = l; i >= 0; --i ){
for (int j = pow(2, i); j < pow(2, i + 1); ++j){
if (2 * j<vNum.size() && vNum[2 * j]>vNum[j]){
int tmp = vNum.at(2 * j);
vNum[2 * j] = vNum[j];
vNum[j] = tmp;
}
if (2 * j+1<vNum.size() && vNum[2 * j+1]>vNum[j]){
int tmp = vNum.at(2 * j+1);
vNum[2 * j+1] = vNum[j];
vNum[j] = tmp;
}
}
}
return vNum[1];
}
void    heapSort(vector<int>& vNum){
vector<int> vTmp;
int t;
while (vNum.size()>1){
t = maxHeap(vNum);
vNum.erase(vNum.begin()+1, vNum.begin() + 2);
vTmp.push_back(t);
}
vNum = vTmp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  排序算法 c-c++