插入排序、希尔排序、选择排序、冒泡排序、归并排序、快速排序、堆排序、基数排序相关信息:
以下均已C++为例:
计数排序
//以投票(洛谷P1271)为例
#include<iostream>
using namespace std;
int main()
{
int n = 0, m = 0,temp=0;
int a[9999]={0};
cin >> n >> m;//输入候选人(n)投票数(m)
for (int i = 0; i < m; ++i)
{
cin >> temp;
a[temp]++;
}
for (int i = 1; i <= n; ++i)
{
for (int j = 0; j < a[i]; ++j)
{
cout << i << " ";
}
}
cout << endl;
system("pause");
return 0;
}
选择排序
#include<iostream>
using namespace std;
int main()
{
int n = 0;
cin >> n;//输入数据数
int a[999]={0};//定义数组
for (int m = 0; m < n; ++m)//输入数据
{
cin >> a[m];
}
for (int i = 0; i < n-1; ++i)
{
for (int j =i+1; j < n; ++j)
{
if (a[j] < a[i])
{
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
for (int w = 0; w < n; ++w)//打印排列好的数据
{
cout << a[w]<<" ";
}
system("pause");
return 0;
}
冒泡排序
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;//输入数据数
int a[999] = { 0 };
for (int o = 0; o < n; ++o)//输入数据
{
cin >> a[o];
}
for (int i = 0; i < n-1; ++i)
{
for (int j = 0; j < n - i - 1; ++j)
{
if (a[j]>a[j+1])
{
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
for (int w = 0; w < n; ++w)//打印排列好的数据
{
cout << a[w]<<" ";
}
system("pause");
return 0;
}
快速排序
void qsort(int a[], int l, int r)//引用数组的地址
{
int i = l, j = r, flag = a[(l + r) / 2], tmp;
do
{
while (a[i] < flag)i++;//从左找比基准数大的数
while (a[j] > flag)j--;//从右找比基准数小的数
if (i <= j)
{
//交换
tmp == a[i];
a[i] = a[j];
a[j] = tmp;
i++;
j--;
}
} while (i <= j)
if (l < j)
qsort(a, l, j);
if (i < r)
qsort(a, i, r);
}
下面这种虽程序框架和快速排序几乎一模一样,但梅西处理的区间长度期望下都会减半,所以是线性复杂度(来源:《深入浅出程序设计竞赛》)
int ans = 0,k;//记录答案,以及求第k小。k是已知值,比如在main函数中赋值过
void findkth(int a[], int l, int r)//引入数组的地址
{
if(l == r)
{
ans = a[l];//区间长度为1时,记录答案
return;
}
int i = l, j = r, flag = a[(l + r) / 2], tmp;
do {
while (a[i] < flag)++i;//从左找比哨兵大的数
while (a[i] > flag)j--;//从右找比哨兵大的数
if (i <= j)
{
//交换
tmp= a[i];
a[i] = a[j];
a[j] = tmp;
}
} while (i <= j);
if (k <= j)findkth(a, l, j);//第k小的数字在左区间
else if (i <= k)findkth(a, i, r);//第k小的数字在右区间
else findkth(a, j + 1, i - 1);//第k小的数字即不在左区间,也不在右区间
}
插入排序:
void insertion_sort(int arr[],int len){
for(int i=1;i<len;i++){
int key=arr[i];
int j=i-1;
while((j>=0) && (key<arr[j])){
arr[j+1]=arr[j];
j--;
}
arr[j+1]=key;
}
}
希尔排序:
template<typename T>
void shell_sort(T array[], int length) {
int h = 1;
while (h < length / 3) {
h = 3 * h + 1;
}
while (h >= 1) {
for (int i = h; i < length; i++) {
for (int j = i; j >= h && array[j] < array[j - h]; j -= h) {
std::swap(array[j], array[j - h]);
}
}
h = h / 3;
}
}
归并排序:
迭代版:
template<typename T> // 整數或浮点数皆可使用,若要使用物件(class)时必须设定"小于"(<)的运算子功能
void merge_sort(T arr[], int len) {
T *a = arr;
T *b = new T[len];
for (int seg = 1; seg < len; seg += seg) {
for (int start = 0; start < len; start += seg + seg) {
int low = start, mid = min(start + seg, len), high = min(start + seg + seg, len);
int k = low;
int start1 = low, end1 = mid;
int start2 = mid, end2 = high;
while (start1 < end1 && start2 < end2)
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++];
while (start1 < end1)
b[k++] = a[start1++];
while (start2 < end2)
b[k++] = a[start2++];
}
T *temp = a;
a = b;
b = temp;
}
if (a != arr) {
for (int i = 0; i < len; i++)
b[i] = a[i];
b = a;
}
delete[] b;
}
递归版:
void Merge(vector<int> &Array, int front, int mid, int end) {
// preconditions:
// Array[front...mid] is sorted
// Array[mid+1 ... end] is sorted
// Copy Array[front ... mid] to LeftSubArray
// Copy Array[mid+1 ... end] to RightSubArray
vector<int> LeftSubArray(Array.begin() + front, Array.begin() + mid + 1);
vector<int> RightSubArray(Array.begin() + mid + 1, Array.begin() + end + 1);
int idxLeft = 0, idxRight = 0;
LeftSubArray.insert(LeftSubArray.end(), numeric_limits<int>::max());
RightSubArray.insert(RightSubArray.end(), numeric_limits<int>::max());
// Pick min of LeftSubArray[idxLeft] and RightSubArray[idxRight], and put into Array[i]
for (int i = front; i <= end; i++) {
if (LeftSubArray[idxLeft] < RightSubArray[idxRight]) {
Array[i] = LeftSubArray[idxLeft];
idxLeft++;
} else {
Array[i] = RightSubArray[idxRight];
idxRight++;
}
}
}
void MergeSort(vector<int> &Array, int front, int end) {
if (front >= end)
return;
int mid = (front + end) / 2;
MergeSort(Array, front, mid);
MergeSort(Array, mid + 1, end);
Merge(Array, front, mid, end);
}
堆排序:
#include <iostream>
#include <algorithm>
using namespace std;
void max_heapify(int arr[], int start, int end) {
// 建立父节点指标和子节点指标
int dad = start;
int son = dad * 2 + 1;
while (son <= end) { // 若子节点指标在范围内才做比较
if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比较两个字节点大小,选择最大的
son++;
if (arr[dad] > arr[son]) // 如果父节点大于子节点代表调整完毕,直接跳出函数
return;
else { // 否则交换父子內容再继续将子节点和孙节点比较
swap(arr[dad], arr[son]);
dad = son;
son = dad * 2 + 1;
}
}
}
void heap_sort(int arr[], int len) {
// 初始化,i从最后一个父节点开始调整
for (int i = len / 2 - 1; i >= 0; i--)
max_heapify(arr, i, len - 1);
// 先將第一个元素和已经排好的元素前一位做交换,再重新调整(刚调整的元素之前的元素),直到排序完毕
for (int i = len - 1; i > 0; i--) {
swap(arr[0], arr[i]);
max_heapify(arr, 0, i - 1);
}
}
int main() {
int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
int len = (int) sizeof(arr) / sizeof(*arr);
heap_sort(arr, len);
for (int i = 0; i < len; i++)
cout << arr[i] << ' ';
cout << endl;
return 0;
}
桶排序:
元素分布在桶中:
然后,元素在每个桶中排序:
#include<iterator>
#include<iostream>
#include<vector>
using namespace std;
const int BUCKET_NUM = 10;
struct ListNode{
explicit ListNode(int i=0):mData(i),mNext(NULL){}
ListNode* mNext;
int mData;
};
ListNode* insert(ListNode* head,int val){
ListNode dummyNode;
ListNode *newNode = new ListNode(val);
ListNode *pre,*curr;
dummyNode.mNext = head;
pre = &dummyNode;
curr = head;
while(NULL!=curr && curr->mData<=val){
pre = curr;
curr = curr->mNext;
}
newNode->mNext = curr;
pre->mNext = newNode;
return dummyNode.mNext;
}
ListNode* Merge(ListNode *head1,ListNode *head2){
ListNode dummyNode;
ListNode *dummy = &dummyNode;
while(NULL!=head1 && NULL!=head2){
if(head1->mData <= head2->mData){
dummy->mNext = head1;
head1 = head1->mNext;
}else{
dummy->mNext = head2;
head2 = head2->mNext;
}
dummy = dummy->mNext;
}
if(NULL!=head1) dummy->mNext = head1;
if(NULL!=head2) dummy->mNext = head2;
return dummyNode.mNext;
}
void BucketSort(int n,int arr[]){
vector<ListNode*> buckets(BUCKET_NUM,(ListNode*)(0));
for(int i=0;i<n;++i){
int index = arr[i]/BUCKET_NUM;
ListNode *head = buckets.at(index);
buckets.at(index) = insert(head,arr[i]);
}
ListNode *head = buckets.at(0);
for(int i=1;i<BUCKET_NUM;++i){
head = Merge(head,buckets.at(i));
}
for(int i=0;i<n;++i){
arr[i] = head->mData;
head = head->mNext;
}
}
基数排序:
int maxbit(int data[], int n) //辅助函数,求数据的最大位数
{
int maxData = data[0]; ///< 最大数
/// 先求出最大数,再求其位数,这样有原先依次每个数判断其位数,稍微优化点。
for (int i = 1; i < n; ++i)
{
if (maxData < data[i])
maxData = data[i];
}
int d = 1;
int p = 10;
while (maxData >= p)
{
//p *= 10; // Maybe overflow
maxData /= 10;
++d;
}
return d;
/* int d = 1; //保存最大的位数
int p = 10;
for(int i = 0; i < n; ++i)
{
while(data[i] >= p)
{
p *= 10;
++d;
}
}
return d;*/
}
void radixsort(int data[], int n) //基数排序
{
int d = maxbit(data, n);
int *tmp = new int[n];
int *count = new int[10]; //计数器
int i, j, k;
int radix = 1;
for(i = 1; i <= d; i++) //进行d次排序
{
for(j = 0; j < 10; j++)
count[j] = 0; //每次分配前清空计数器
for(j = 0; j < n; j++)
{
k = (data[j] / radix) % 10; //统计每个桶中的记录数
count[k]++;
}
for(j = 1; j < 10; j++)
count[j] = count[j - 1] + count[j]; //将tmp中的位置依次分配给每个桶
for(j = n - 1; j >= 0; j--) //将所有桶中记录依次收集到tmp中
{
k = (data[j] / radix) % 10;
tmp[count[k] - 1] = data[j];
count[k]--;
}
for(j = 0; j < n; j++) //将临时数组的内容复制到data中
data[j] = tmp[j];
radix = radix * 10;
}
delete []tmp;
delete []count;
}
相关推荐:
1.0 十大经典排序算法 | 菜鸟教程 (runoob.com)https://www.runoob.com/w3cnote/ten-sorting-algorithm.html
首页 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)https://www.luogu.com.cn/
动画阐释各种排序算法_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV13Y4y1H7j5