一、选择排序
原理:
1、依次比较数组中元素,从而记录下数组中最小的元素
2、将最小元素与数组第一个元素交换
3、依次比较数组中剩余元素,从而记录下剩余数组中最小的元素 与数组第二个元素交换,以此类推
特点:
需要大约(N-1)+(N-2)+....+1 ~ N^2/2次比较和N次交换,算法的时间效率取决于比较的次数。
代码:
#include<iostream>
using namespace std;
template <class T>
void select_sort(T *a, int len)
{
for (int i = 0; i < len; i++){
int min = i;
for (int j = i + 1; j < len; j++)
if (a[i] > a[j]) min = j;
T t = a[min];
a[min] = a[i];
a[i] = t;
}
for (int i = 0; i != len; i++)
{
cout << a[i] <<" ";
}
}
int main()
{
int a[3]={1, 3, 2};
select_sort(a, 3);
system("pause");
return 0;
}
结果:
二、插入排序
原理:
1、从数组的第一个元素出发 不断的向右移动
2、每走一步把之前的元素排序
特点:
插入排序所需要的时间取决于输入中元素的初始顺序。对于一个很大的且其中的元素已经有序的数组进行排序要比随机的数组快的多。至少要进行N-1次比较和0次交换,最多需要大约N^2/2次比较和交换。平均N^2/4次比较和交换。
代码:
#include<iostream>
using namespace std;
template <class T>
void insert_sort(T *a, int len)
{
int i, j;
for (i = 1; i < len; i++){
T tem = *(a + i);
for (j = i; j != 0 && *(a + j - 1) > tem; j--)
*(a + j) = *(a + j - 1);
*(a + j) = tem;
}
for (int n = 0; n != len; n++)
{
cout << a[n] <<" ";
}
}
int main()
{
int a[3]={1, 3, 2};
insert_sort(a, 3);
system("pause");
return 0;
}
三、冒泡排序
原理:
1、从数组的第一个元素开始,比较前两个元素大小,大的替换较后的位置
2、在依次比较二三号位置的数值,直到数组末尾n为一个循环,这时最大的数移动到数组末尾,其他顺序不变
3、按照上述方法比较前n-1个元素
特点:
最简单基本的的排序方式
代码
#include<iostream>
using namespace std;
template <class T>
void bubble_sort(T *a, int len)
{
T tem;
for (int i = 1; i != len; i++)
{
for (int j = i; j != len; j++)
{
if (a[j] < a[j - 1])
{
tem = a[j];
a[j] = a[j - 1];
a[j - 1] = tem;
}
}
}
for (int i = 0; i < len; i++)
{
cout << a[i];
}
}
int main()
{
int a[3]={1, 3, 2};
insert_sort(a, 3);
system("pause");
return 0;
}
四、桶排序
简单的桶排序:
原理:
1、给定一组数a[],其中最大的数为max,定义一个数组b[],长度为max+1
2、将数组中的数都置零,遍历给定的a[]中的元素i, 在对应数组b[]索引为i的位置加1
3、最终输出b中元素值的索引
特点:
代码:
#include<iostream>
using namespace std;
template <class T>
void insert_sort(T *a, int len)
{
int m, n;
T *b = new T[len+1];
for (n = 0; n != len + 1; n++)
{
b[n] = 0;
}
for (m = 0; m != len; m++)
{
b[a[m]]++;
}
for (int i = 0; i < len + 1; i++)
{
for (int j = 0; j != b[i]; j++)
cout << i;
}
}
int main()
{
int a[3]={1, 3, 2};
insert_sort(a, 3);
system("pause");
return 0;
}
复杂一点的桶排序
原理:
和简单的桶排序差不多只不多数组不在是max+1,而是分成几个区间
每个桶用一个链表表示,桶中放着相应的元素
代码:摘自https://www.cnblogs.com/melons/p/5791842.html
//每一个节点的结构
struct node
{
int key; //关键字,在桶中统计桶中数据量,在数据节点中就是节点的数据
struct node *next;
};
//声明:
void PrintBucketSort(node** bucket, int bucket_size);
int f(int x);
void BucketSort(int* a, int size,int bucket_size)
{
assert(a);
//给桶申请空间
node** bucket = new node*[bucket_size*sizeof(node)];
//初始化
for (int i = 0; i < bucket_size; ++i)
{
bucket[i] = new node[sizeof(node)]; //每一个桶
bucket[i]->key = 0;
bucket[i]->next = nullptr;
}
for (int j = 0; j < size; ++j)
{
node* sub_node = new node[sizeof(node)]; //桶下的每一个节点
sub_node->key = a[j];
sub_node->next = nullptr;
//计算这数据在哪个桶中
int num = f(a[j]);
//让一个指针指向这个桶号的头
node* sub_head = bucket[num];
//开始插入
if (sub_head->next == nullptr)
{
bucket[num]->next = sub_node;
bucket[num]->key++;
}
//该桶号不为空,那么插入排序
else
{
while (sub_head->next != nullptr && sub_node->key >= sub_head->next->key)
{
sub_head = sub_head->next;
}
sub_node->next = sub_head->next;
sub_head->next = sub_node;
bucket[num]->key++;
}
}
//打印
PrintBucketSort(bucket, bucket_size);
}
//映射函数
int f(int x)
{
return (x / 10);
}
//打印
void PrintBucketSort(node** bucket, int bucket_size)
{
//多少桶链(桶号)
for (int i = 0; i < bucket_size; ++i)
{
node* cur = bucket[i]->next;
while (cur)
{
cout << cur->key << " ";
cur = cur->next;
}
}
cout << endl;
}
void Test7()
{
int a[10] = { 49, 38, 35, 97, 76, 73, 27, 49, 34, 78 };
cout << "桶排序" << endl;
BucketSort(a, 10, 10); //桶数据最大才97,所以需要10个桶
}
五、归并排序
原理:要将一个数组排序,先将他分成两半分别进行排序,然后再把结果归并起来
解释见https://blog.csdn.net/a130737/article/details/38228369
特点:能够保证将任意长度为N的数组排序所需时间和NLogN成正比,缺点是所需的空间和NLogN成正比。
代码:
#include<iostream>
using namespace std;
template<class T>
void Merge(T* A, T* left, int leftCount, int *right, int rightCount)
{
int i = 0;
int j = 0;
int n = 0;
while (i < leftCount && j < rightCount)
{
if (*(left + i) < *(right + j))
{
*(A + n) = *(left + i);
i++; n++;
}
else
{
*(A + n) = *(right + j);
j++; n++;
}
}
while (i < leftCount) {
*(A + n) = *(left + i); n++; i++;
}
while (j < rightCount) {
*(A + n) = *(right + j); n++; j++;
}
}
template<class T>
void Merge_sort(T *A, int n)
{
int mid, i;
T *left, *right;
if (n < 2) return;
mid = n / 2;
left = new T[mid];
right = new T[n - mid];
for (i = 0; i < mid; i++) *(left + i) = *(A + i);
for (i = mid; i < n; i++) *(right+i - mid) = *(A + i);
Merge_sort(left, mid);
Merge_sort(right, mid);
Merge(A, left, mid, right, n - mid);
delete[] right;
delete[] left;
}
int main()
{
int A[] = { 6, 2, 3, 1, 9, 10, 15, 13, 12, 17 }; // creating an array of integers.
int i, numberOfElements;
numberOfElements = sizeof(A) / sizeof(A[0]);
// Calling merge sort to sort the array.
Merge_sort(A, numberOfElements);
for (i = 0; i < numberOfElements; i++)
cout << " " << A[i];
system("pause");
return 0;
}
各算法复杂度: