一、合并排序
1.思路:
将包含n个元素的序列均分成各自包含n/2个元素的子序列,然后对这两个子序列递归划分,最后把已经排好序的子序列合并成一个有序序列。
2.代码:
#include <iostream>
using namespace std;
void Merge(int *array, int low, int middle, int high) //合并
{
int *A = new int[high - low + 1]; //临时数组,存储个数为high - low + 1个数据
int i = low;
int j = middle + 1;
int k = 0;
while(i <= middle && j <= high) //直至前半部或后半部数据完全录入暂存
{
if(array[i] < array[j]) //如果前半部的数据小于后半部的,前半部数据暂存
A[k++] = array[i++];
else //否则后半部数据暂存,并下标自加
A[k++] = array[j++];
}
while(i <= middle) //保证前半部数据录入暂存
A[k++] = array[i++];
while(j <= high) //保证后半部数据录入暂存
A[k++] = array[j++];
for(i = low; i <= high; i++) //将暂存的数据重新填充至array[low]--array[high]中
array[i] = A[i - low];
}
void MergeSort(int *array, int low, int high)
{
int middle; //二分
if(low < high)
{
middle = (low + high) / 2; //二分
MergeSort(array, low, middle); //前半部
MergeSort(array, middle + 1, high); //后半部
Merge(array, low, middle, high); //合并
}
}
int main()
{
/*int n;
cin>>n; //录入需要排列的个数
int *array = new int[n];
cout<<endl<<"请输入数据:"<<endl;
for(int i = 0; i < n; i++)
{
cin>>array[i]; //录入未排序的数据
}*/
int n=10;
int array[10]={3,2,5,7,3,8,4,5,8,6};
MergeSort(array, 0, n - 1); //进行排序
cout<<"排列后数据:"<<endl;
for(int j = 0; j < n; j++) //输出排列结果
{
cout<<array[j]<<" ";
}
cout<<endl;
return 0;
}
二、快速排序
1.思想:
把A分成两个部分,支点为q,并且满足左边的都<A[q],右边的都>A[q],子问题解决了原问题就解决了。
2.代码:
#include<iostream>
using namespace std;
int partition(int *arr, int left, int right) //找基准数 划分
{
int temp = arr[left];//支点
int i = left + 1 ;//左指针,寻找>支点数据的位置
int j = right;//右指针,寻找<支点数据的位置
while(i <= j)
{
while (arr[i] < temp) i++;//左位置
while (arr[j] > temp) j--;//右位置
if (i < j)
swap(arr[i++], arr[j--]);
else i++;
}
swap(arr[j], arr[left]);
return j;
}
void quick_sort(int arr[], int left, int right)
{
if (left > right)
return;
int j = partition(arr, left, right);
quick_sort(arr, left, j - 1);
quick_sort(arr, j + 1, right);
}
int main()
{
int a[10]={3,1,5,7,4,7,9,7,2,4};
quick_sort(a,0,9);
for(int i=0;i<=9;i++)
cout<<a[i]<<' ';
return 0;
}
三、冒泡、插入排序
#include<iostream>
using namespace std;
void sort1(int *a,int n)//冒泡排序
{
int i,j,tmp;
for(i=0;i<n;i++)
for(j=i+1;j<n;j++)
if(a[i]>a[j])
{
tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}
void sort2(int *a,int n)//插入排序
{
int i,j,k;
for(i=1;i<n;i++)
{
for(j=i-1;j>=0;j--)
if(a[i]>a[j])
break;
int tmp=a[i];
for(k=i-1;k>j;k--)
a[k+1]=a[k];
a[j+1]=tmp;
}
}
int partition(int *a,int left,int right)
{
int tmp=a[left];
int i=left+1;
int j=right;
while(i<=j)
{
while(a[i]<tmp)i++;
while(a[j]>tmp)j--;
if(i<j)
swap(a[i++],a[j--]);
else i++;
}
swap(a[j],a[left]);
return j;
}
void sort3(int *a,int left,int right)//快速排序
{
if(left>right)return;
int j=partition(a,left,right);
sort3(a,left,j-1);
sort3(a,j+1,right);
}
void merge(int *a,int left,int middle,int right)
{
int *A = new int[right-left + 1];
int i = left;
int j = middle + 1;
int k = 0;
while(i <= middle && j <= right) //直至前半部或后半部数据完全录入暂存
{
if(a[i] < a[j]) //如果前半部的数据小于后半部的,前半部数据暂存
A[k++] = a[i++];
else //否则后半部数据暂存,并下标自加
A[k++] = a[j++];
}
while(i <= middle) //保证前半部数据录入暂存
A[k++] = a[i++];
while(j <= right) //保证后半部数据录入暂存
A[k++] = a[j++];
for(i = left; i <= right; i++) //将暂存的数据重新填充至array[low]--array[high]中
a[i] = A[i - left];
}
void sort4(int *a,int left,int right)//归并排序
{
int middle;
if(left<right)
{
middle=(left+right)/2;
sort4(a,left,middle);
sort4(a,middle+1,right);
merge(a,left,middle,right);
}
}
int main()
{
int n=5;
int *a=new int[n];
for(int i=0;i<n;i++)
cin>>a[i];
sort4(a,0,n-1);
for(int j=0;j<n;j++)
cout<<a[j]<<' ';
}
四、基数排序
1.思想:
2.代码:
/*
* 获取数组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);
}
3.参考:
https://www.cnblogs.com/skywang12345/p/3603669.html
五、计数排序
1.思想:
设置MXA(待排序数组的最大值)个桶,分别将数放入各个桶,再收集即可。
2.代码:
#include<iostream>
using namespace std;
int main() {
int book[100] = {0};//标志位,标记桶内数据量
int input[11];
int heap[100] = {0};//初始化堆,排序0到100之间的数,heap[排序范围最大值]
int i,j;
for (size_t i = 1; i <=10 ; i++)
{
cin >> input[i];
book[input[i]] += 1;
heap[input[i]] = 1;
}
for (size_t i = 0; i <100 ; i++)
{
if (heap[i]==1) {
for ( j = 1;j<=book[i]; j++)
{
cout << i << " ";//输出排序结果
}
}
}
cout << endl;
getchar();
return 0;
}
六、堆排序
1.思想:
将数组建成最大(小)堆,然后依次删除最大元素即可。
2.代码:
3.参考:
https://www.cnblogs.com/chengxiao/p/6129630.html