冒泡排序
#include<iostream>
using namespace std;
int main()
{
int a[5] = { 5,4,3,2,1 };
int i, j;
for (i = 0; i < 4; i++)
{
bool flag = true;
for (j = 0; j < 4 - i; j++)
{
if (a[j] > a[j + 1])
{
swap(a[j], a[j + 1]);
flag = false;
}
}
if (flag) break;
}
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
return 0;
}
选择排序
#include<iostream>
using namespace std;
int main()
{
int a[5] = { 5,4,3,2,1 };
int i, j;
for (i = 0; i < 4; i++)
for (j = i + 1; j < 5; j++)
if (a[j] < a[i])
swap(a[j], a[i]);
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
return 0;
}
插入排序
#include<iostream>
using namespace std;
int main()
{
int a[100];
int i, j, temp;
for (i = 0; i < 5; i++)
cin >> a[i];
for (j = 1; j < 5; j++)
for (i = 0; i < j; i++)
{
if (a[j] < a[i])
{
int temp = a[j];
for (int m = j; m > i; m--)
a[m] = a[m - 1];
a[i] = temp;
break;
}
}
for (i = 0; i < 5; i++)
cout << a[i] << ' ';
return 0;
}
快速排序
#include<iostream>
using namespace std;
void QuickSort(vector<int>& a, int l, int r)
{
if (l >= r) return;
int temp = a[l];
int i = l, j = r;
while (i < j)
{
while (i<j && a[j]>temp) j--;
if (i < j) a[i++] = a[j];
while (i<j && a[i]<temp) i++;
if (i < j) a[j--] = a[i];
}
a[i] = temp;
QuickSort(a, l, i - 1);
QuickSort(a, i + 1, r);
}
int main()
{
vector<int>a{ 5,4,3,2,1 };
QuickSort(a, 0, a.size() - 1);
for (int i = 0; i < a.size(); i++)
cout << a[i] << ' ';
return 0;
}
希尔排序
/*
* 对希尔排序中的单个组进行排序
*
* 参数说明:
* a -- 待排序的数组
* n -- 数组总的长度
* i -- 组的起始位置
* gap -- 组的步长
*
* 组是"从i开始,将相隔gap长度的数都取出"所组成的!
*/
void group_sort(int a[], int n, int i, int gap)
{
int j;
for (j = i + gap; j < n; j += gap)
{
// 如果a[j] < a[j-gap],则寻找a[j]位置,并将后面数据的位置都后移。
if (a[j] < a[j - gap])
{
int tmp = a[j];
int k = j - gap;
while (k >= 0 && a[k] > tmp)
{
a[k + gap] = a[k];
k -= gap;
}
a[k + gap] = tmp;
}
}
}
/*
* 希尔排序
*
* 参数说明:
* a -- 待排序的数组
* n -- 数组的长度
*/
void shell_sort2(int a[], int n)
{
int i, gap;
// gap为步长,每次减为原来的一半。
for (gap = n / 2; gap > 0; gap /= 2)
{
// 共gap个组,对每一组都执行直接插入排序
for (i = 0; i < gap; i++)
group_sort(a, n, i, gap);
}
}
堆排序
/*
* (最大)堆的向下调整算法
*
* 注:数组实现的堆中,第N个节点的左孩子的索引值是(2N+1),右孩子的索引是(2N+2)。
* 其中,N为数组下标索引值,如数组中第1个数对应的N为0。
*
* 参数说明:
* a -- 待排序的数组
* start -- 被下调节点的起始位置(一般为0,表示从第1个开始)
* end -- 截至范围(一般为数组中最后一个元素的索引)
*/
void maxheap_down(int a[], int start, int end)
{
int c = start; // 当前(current)节点的位置
int l = 2 * c + 1; // 左(left)孩子的位置
int tmp = a[c]; // 当前(current)节点的大小
for (; l <= end; c = l, l = 2 * l + 1)
{
// "l"是左孩子,"l+1"是右孩子
if (l < end && a[l] < a[l + 1])
l++; // 左右两孩子中选择较大者,即m_heap[l+1]
if (tmp >= a[l])
break; // 调整结束
else // 交换值
{
a[c] = a[l];
a[l] = tmp;
}
}
}
/*
* 堆排序(从小到大)
*
* 参数说明:
* a -- 待排序的数组
* n -- 数组的长度
*/
void heap_sort_asc(int a[], int n)
{
int i;
// 从(n/2-1) --> 0逐次遍历。遍历之后,得到的数组实际上是一个(最大)二叉堆。
for (i = n / 2 - 1; i >= 0; i--)
maxheap_down(a, i, n - 1);
// 从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (i = n - 1; i > 0; i--)
{
// 交换a[0]和a[i]。交换后,a[i]是a[0...i]中最大的。
swap(a[0], a[i]);
// 调整a[0...i-1],使得a[0...i-1]仍然是一个最大堆。
// 即,保证a[i-1]是a[0...i-1]中的最大值。
maxheap_down(a, 0, i - 1);
}
}
归并排序(从下到上)
/*
* 对数组a做若干次合并:数组a的总长度为len,将它分为若干个长度为gap的子数组;
* 将"每2个相邻的子数组" 进行合并排序。
*
* 参数说明:
* a -- 待排序的数组
* len -- 数组的长度
* gap -- 子数组的长度
*/
void merge_groups(int a[], int len, int gap)
{
int i;
int twolen = 2 * gap; // 两个相邻的子数组的长度
// 将"每2个相邻的子数组" 进行合并排序。
for (i = 0; i + 2 * gap - 1 < len; i += (2 * gap))
{
merge(a, i, i + gap - 1, i + 2 * gap - 1);
}
// 若 i+gap-1 < len-1,则剩余一个子数组没有配对。
// 将该子数组合并到已排序的数组中。
if (i + gap - 1 < len - 1)
{
merge(a, i, i + gap - 1, len - 1);
}
}
/*
* 归并排序(从下往上)
*
* 参数说明:
* a -- 待排序的数组
* len -- 数组的长度
*/
void merge_sort_down2up(int a[], int len)
{
int n;
if (a == NULL || len <= 0)
return;
for (n = 1; n < len; n *= 2)
merge_groups(a, len, n);
}
归并排序(从上到下)
/*
* 将一个数组中的两个相邻有序区间合并成一个
*
* 参数说明:
* a -- 包含两个有序区间的数组
* start -- 第1个有序区间的起始地址。
* mid -- 第1个有序区间的结束地址。也是第2个有序区间的起始地址。
* end -- 第2个有序区间的结束地址。
*/
void merge(int a[], int start, int mid, int end)
{
int* tmp = (int*)malloc((end - start + 1) * sizeof(int)); // tmp是汇总2个有序区的临时区域
int i = start; // 第1个有序区的索引
int j = mid + 1; // 第2个有序区的索引
int k = 0; // 临时区域的索引
while (i <= mid && j <= end)
{
if (a[i] <= a[j])
tmp[k++] = a[i++];
else
tmp[k++] = a[j++];
}
while (i <= mid)
tmp[k++] = a[i++];
while (j <= end)
tmp[k++] = a[j++];
// 将排序后的元素,全部都整合到数组a中。
for (i = 0; i < k; i++)
a[start + i] = tmp[i];
free(tmp);
}
/*
* 归并排序(从上往下)
*
* 参数说明:
* a -- 待排序的数组
* start -- 数组的起始地址
* endi -- 数组的结束地址
*/
void merge_sort_up2down(int a[], int start, int end)
{
if (a == NULL || start >= end)
return;
int mid = (end + start) / 2;
merge_sort_up2down(a, start, mid); // 递归排序a[start...mid]
merge_sort_up2down(a, mid + 1, end); // 递归排序a[mid+1...end]
// a[start...mid] 和 a[mid...end]是两个有序空间,
// 将它们排序成一个有序空间a[start...end]
merge(a, start, mid, end);
}
桶排序
/*
* 桶排序
*
* 参数说明:
* a -- 待排序数组
* n -- 数组a的长度
* max -- 数组a中最大值的范围
*/
void bucketSort(int a[], int n, int max)
{
int i, j;
int buckets[max];
// 将buckets中的所有数据都初始化为0。
memset(buckets, 0, max * sizeof(int));
// 1. 计数
for (i = 0; i < n; i++)
buckets[a[i]]++;
// 2. 排序
for (i = 0, j = 0; i < max; i++)
{
while ((buckets[i]--) > 0)
a[j++] = i;
}
}
基数排序
/*
* 获取数组a中最大值
*
* 参数说明:
* a -- 数组
* n -- 数组长度
*/
int get_max(int a[], int n)
{
int i, max;
max = a[0];
for (i = 1; i < n; i++)
if (a[i] > max)
max = a[i];
return max;
}
/*
* 对数组按照"某个位数"进行排序(桶排序)
*
* 参数说明:
* a -- 数组
* n -- 数组长度
* exp -- 指数。对数组a按照该指数进行排序。
*
* 例如,对于数组a={50, 3, 542, 745, 2014, 154, 63, 616};
* (01) 当exp=1表示按照"个位"对数组a进行排序
* (02) 当exp=10表示按照"十位"对数组a进行排序
* (03) 当exp=100表示按照"百位"对数组a进行排序
* ...
*/
void count_sort(int a[], int n, int exp)
{
int output[n]; // 存储"被排序数据"的临时数组
int i, buckets[10] = { 0 };
// 将数据出现的次数存储在buckets[]中
for (i = 0; i < n; i++)
buckets[(a[i] / exp) % 10]++;
// 更改buckets[i]。目的是让更改后的buckets[i]的值,是该数据在output[]中的位置。
for (i = 1; i < 10; i++)
buckets[i] += buckets[i - 1];
// 将数据存储到临时数组output[]中
for (i = n - 1; i >= 0; i--)
{
output[buckets[(a[i] / exp) % 10] - 1] = a[i];
buckets[(a[i] / exp) % 10]--;
}
// 将排序好的数据赋值给a[]
for (i = 0; i < n; i++)
a[i] = output[i];
}
/*
* 基数排序
*
* 参数说明:
* a -- 数组
* n -- 数组长度
*/
void radix_sort(int a[], int n)
{
int exp; // 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
int max = get_max(a, n); // 数组a中的最大值
// 从个位开始,对数组a按"指数"进行排序
for (exp = 1; max / exp > 0; exp *= 10)
count_sort(a, n, exp);
}
以上为各个排序算法的原理,在实际应用中能sort就尽量sort!