目录


算法性能总结

Algorithm:十大经典排序算法C++实现及总结_快速排序

1、冒泡排序

Algorithm:十大经典排序算法C++实现及总结_数据结构_02

//1、Bubble Sort 冒泡排序
void bubbleSort(int a[], int length)
{
if (length < 2)
return;
for (int i = 0; i < length - 1; i++) //需length-1趟排序确定后length-1个数,剩下第一个数不用排序;
{
for (int j = 0; j < length - 1 - i; j++)
{
if (a[j + 1] < a[j])
{
int temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
}

2、选择排序

Algorithm:十大经典排序算法C++实现及总结_堆排序_03

//2、Select Sort 选择排序
void selectSort(int a[], int length)
{
if (length < 2)
return;
for (int i = 0; i < length; i++)
{
int minIndex = i;
for (int j = i + 1; j < length; j++) //已确定a[0]~a[i-1],从i-1开始查找最小的数,然后与a[i]交换位置;
{
if (a[j] < a[minIndex])
minIndex = j;
}
int temp = a[i];
a[i] = a[minIndex];
a[minIndex] = temp;
}
}

3、插入排序

Algorithm:十大经典排序算法C++实现及总结_快速排序_04

//3、Insert Sort 插入排序
void insertSort(int a[], int length)
{
if (length < 2)
return;
for (int i = 1; i < length; i++) //现在进行插入的是a[i]
{
int cur = a[i];
int j = i;
while (j > 0 && a[j - 1] > cur) //如果前面的数比cur,说明cur要插在它们前面,即将它们后移一个位置;
{
a[j] = a[j - 1];
j--;
}
a[j] = cur;
}
}

4、希尔排序

Algorithm:十大经典排序算法C++实现及总结_排序算法_05

//4、Shell Sort 希尔排序
void shellSort(int a[], int length)
{
if (length < 2)
return;
int gap = length / 2; //整个数组分为gap个组,即每隔 gap-1 个位置的元素为一组
while (gap > 0) //最终整个数组分为一组 即所有元素为一组;
{
for (int i = gap; i < length; i++)
{
int cur = a[i];
int preIndex = i - gap;
while (preIndex >= 0 && a[preIndex] > cur) //对每一组元素进行插入排序
{
a[i] = a[preIndex];
preIndex -= gap;
}
a[preIndex + gap] = cur;
}
gap /= 2;
}
}

5、归并排序

Algorithm:十大经典排序算法C++实现及总结_数据结构_06

//5、Merge Sort 归并排序
void merge(int a[], int left, int mid, int right);

void mergeSort(int a[], int left, int right) // left需要排序数组 a[] 的左端下标,right为右端下标
{
int length = right - left + 1;
if (length < 2)
return;

int mid = (right + left) / 2;

mergeSort(a, 0, mid);
mergeSort(a, mid + 1, right);
merge(a, left, mid, right); //调用merge函数 将二者合并
}

void merge(int a[], int left, int mid, int right) //将数组a 的两个子数组a[left] ~ a[mid] 与 a[mid+1] ~ a[right] 合并
{
int len = right - left + 1;

vector<int> temp;
int i = left, j = mid + 1;
for (; i <= mid && j <= right;)
{
if (a[i] < a[j])
{
temp.push_back(a[i]);
i++;
}
else
{
temp.push_back(a[j]);
j++;
}
}
while (i <= mid)
temp.push_back(a[i++]); //此时必有一个子数组没有走完 需要把剩下的元素全部放进vector
while (j <= right)
temp.push_back(a[j++]);

for (int i = left, k = 0; i <= right; i++) //把vector中已排完序的元素存入数组a[left]~a[right]
{
a[i] = temp[k++];
}
}

6、快速排序

Algorithm:十大经典排序算法C++实现及总结_数据结构_07

//6、Quick Sort 快速排序
void quickSort(int a[], int left, int right)
{
if (left >= right)
return;
int key = a[left]; //以第一个数为基数进行快排;
int pointL = left, pointR = right;

while (pointL < pointR)
{
//一定要先动右指针,否则右指针所指向的元素无处存放
while (pointR > pointL && a[pointR] >= key) //若右指针指向的元素大于key 则右指针左移,直到右指针指向的元素小于key 或者 左右指针坐标相同
pointR--;
a[pointL] = a[pointR]; //把这个小于key的元素放到key的左边,即左指针指向的位置

while (pointR > pointL && a[pointL] <= key) //若左指针指向的元素小于key 则左指针右移,直到左指针指向的元素大于key 或者 左右指针坐标相同
pointL++;
a[pointR] = a[pointL]; //把这个大于key的元素放到key的右边,即右指针指向的位置
}
a[pointR] = key; //此时左右指针指向同一位置,这个位置就是key应该放的位置

//对key两边的元素同样使用快排
quickSort(a, left, pointR - 1);
quickSort(a, pointR + 1, right);
}

7、计数排序

Algorithm:十大经典排序算法C++实现及总结_堆排序_08

//7、Counting Sort 计数排序
void countingSort(int a[], int length)
{
if (length < 2)
return;
int min = a[0], max = a[0];
int bios; //偏移量

for (int i = 0; i < length; i++) //找最大最小值
{
if (a[i] < min)
min = a[i];
if (a[i] > max)
max = a[i];
}

bios = 0 - min;
vector<int> temp(max - min + 1, 0);

for (int i = 0; i < length; i++) //把出现了的元素作为temp的下标 并置1;
{
temp[a[i] + bios]++;
}

int index = 0;
for (int i = 0; i < max - min + 1; i++) //顺序扫描以便vector即可
{
while (temp[i])
{
a[index++] = i - bios;
temp[i]--;
}
}
}

8、桶排序

Algorithm:十大经典排序算法C++实现及总结_快速排序_09

//8、Bucket Sort 桶排序
void bucketSort(int a[], int length)
{
if (length < 2)
return;
int min = a[0], max = a[0];
for (int i = 0; i < length; i++)
{
if (a[i] < min)
min = a[i];
if (a[i] > max)
max = a[i];
}

int buckNum = (max - min) / length + 1; //桶的数量
vector<vector<int>> bucketArr;
for (int i = 0; i < buckNum; i++)
{
vector<int> temp;
bucketArr.push_back(temp);
}

//每个元素入桶
for (int i = 0; i < length; i++)
{
int num = (a[i] - min) / length;
bucketArr[num].push_back(a[i]);
}

//对每个桶排序 并且排序完后赋值
int index = 0;
for (int i = 0; i < bucketArr.size(); i++)
{
if (bucketArr[i].size())
{
sort(bucketArr[i].begin(), bucketArr[i].end()); //快排
for (int j = 0; j < bucketArr[i].size(); j++)
{
a[index++] = bucketArr[i][j];
}
}
}
}

9、基数排序

Algorithm:十大经典排序算法C++实现及总结_算法_10

//9、Base Sort 基数排序
void baseSort(int a[], int length)
{
//得到最大位数;
int max = a[0];
int d = 0;//最大位数
for (int i = 0; i < length; i++)
{
if (a[i] > max)
max = a[i];
}
while (max)
{
max /= 10;
d++;
}

int factor = 1;
for (int i = 1; i <= d; i++) //从个位数排到d位数
{
vector<int> bucket[10]; //初始化十个桶
for (int i = 0; i < length; i++)
{
int temp = (a[i] / factor) % 10; //得到a[i]的now_d位数,并放入对应桶中
bucket[temp].push_back(a[i]);
}
int j = 0;
for (int i = 0; i < 10; i++) //遍历十个桶,按从小到大顺序放入原数组
{
int size = bucket[i].size();
for (int k = 0; k < size; k++)
{
a[j++] = bucket[i][k];
}
bucket[i].clear(); //桶置空
}
factor *= 10;
}
}

10、堆排序

Algorithm:十大经典排序算法C++实现及总结_快速排序_11

//10、Heap Sort 堆排序   大顶堆做出来顺序,小顶堆做出来逆序
void fixDown(int a[], int i, int length);
void swap(int a[], int i, int j);

void heapSort(int a[], int length)
{
//先对 a 堆化
for (int i = length / 2 - 1; i >= 0; i--) // 完成后 此时a已经是合法的小顶堆
{
fixDown(a, i, length); //把i当前小顶堆的根节点
}
//调整堆结构
for (int x = length - 1; x > 0; x--)
{
//把堆顶元素(0号元素)和末尾元素对调;
swap(a, 0, x);
//缩小堆的范围,对堆顶元素进行向下调整;
fixDown(a, 0, x);
}
}

void fixDown(int a[], int i, int length)
{
//找到左右子孩子
int left = 2 * i + 1;
int right = 2 * i + 2;
int min = left; //min指向左右孩子中较小的那个
if (left >= length) //若左孩子越界则右孩子必越界
return;
if (right < length && a[right] < a[left]) //右孩子越界或者右孩子值比左孩子小
min = right;

//如果a[i]比这两个孩子的值都要小,则不用调整;
if (a[i] < a[min])
return;

//否则,其值和a[i]交换;
swap(a, i, min);
//小孩子那个位置的值发生变化,i变更为小孩子的那个位置,于是递归调整;
fixDown(a, min, length);
}
void swap(int a[], int i, int j)
{
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

//1、Bubble Sort 冒泡排序
void bubbleSort(int a[], int length);
//2、Select Sort 选择排序
void selectSort(int a[], int length);
//3、Insert Sort 插入排序
void insertSort(int a[], int length);
//4、Shell Sort 希尔排序
void shellSort(int a[], int length);
//5、Merge Sort 归并排序
void merge(int a[], int left, int mid, int right);
void mergeSort(int a[], int left, int right) ;
//6、Quick Sort 快速排序
void quickSort(int a[], int left, int right);
//7、Counting Sort 计数排序
void countingSort(int a[], int length);
//8、Bucket Sort 桶排序
void bucketSort(int a[], int length);
//9、Base Sort 基数排序
void baseSort(int a[], int length);
//10、Heap Sort 堆排序 大顶堆做出来顺序,小顶堆做出来逆序
void fixDown(int a[], int i, int length);
void swap(int a[], int i, int j);
void heapSort(int a[], int length)

int main()
{
int a[8] = {3, 1, 5, 4, 5, 8, 7, 10};
// bubbleSort(a, 8);
// selectSort(a,8);
// insertSort(a, 8);
// shellSort(a, 8);
// mergeSort(a, 0, 7);
// quickSort(a, 0, 7);
// countingSort(a, 8);
// bucketSort(a, 8);
// baseSort(a, 8);
heapSort(a, 8);
for (int i = 0; i < 8; i++)
cout << a[i] << ' ';

return 0;
}