1.冒泡排序:
依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。
图解:
#include<stdio.h>
int main(){
int i,j,n,a[110],t,tt,count;
scanf("%d",&t);
while(t--){
count=0;
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(i=0;i<n-1;i++){
for(j=0;j<n-i-1;j++){
if(a[j]>a[j+1]){
count++;
tt=a[j];
a[j]=a[j+1];
a[j+1]=tt;
}
}
}
printf("%d\n",count);
}
return 0;
}
2.选择排序:
每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。
#include<iostream>
#include<cstdio>
using namesapce std;
void SelectionSort(int *num,int n)
{
int i = 0;
int min = 0;
int j = 0;
int tmp = 0;
for(i = 0;i < n-1;i++)
{
min = i;//每次讲min置成无序组起始位置元素下标
for(j = i;j < n;j++)//遍历无序组,找到最小元素。
{
if(num[min]>num[j])
{
min = j;
}
}
if(min != i)//如果最小元素不是无序组起始位置元素,则与起始元素交换位置
{
tmp = num[min];
num[min] = num[i];
num[i] = tmp;
}
}
}
int main()
{
int num[6] = {5,4,3,2,9,1};
int i = 0;
SelectionSort(num,6);//这里需要将数列元素个数传入。有心者可用sizeof在函数内求得元素个数。
for(i = 0;i < 6;i++)
{
printf("%d ",num[i]);
}
return 0;
}
3.插入排序:
每步将一个待排序的纪录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。
#include<iostream>
#include<cstdio>
using namespace std;
int main(void)
{
int n, x, i, count = 0;
int a[10];
scanf("%d", &n);
for(i = 0; i < n; i++){
scanf("%d", &a[i]);
}
scanf("%d", &x);
if(x >= a[n-1]){
for(i = 0; i < n; i++)
printf("%d ", a[i]);
printf("%d\n", x);
}
if(x <= a[0]){
printf("%d ", x);
for(i = 0; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
if(x > a[0]&& x < a[n-1]){
for(i = 0; i < n; i++)
{
if(a[i] <= x){
printf("%d ", a[i]);
count++;
}
if(a[i] >= x){
printf("%d ", x);
break;
}
}
for(i = count; i < n; i++)
printf("%d ", a[i]);
printf("\n");
}
return 0;
}
4.希尔排序:
是插入排序的一种。是针对直接插入排序算法的改进。不稳定。
#include <iostream>
using namespace std;
int a[] = {70,30,40,10,80,20,90,100,75,60,45};
void shell_sort(int a[],int n);
int main()
{
cout<<"Before Sort: ";
for(int i=0; i<11; i++)
cout<<a[i]<<" ";
cout<<endl;
shell_sort(a, 11);
cout<<"After Sort: ";
for(int i=0; i<11; i++)
cout<<a[i]<<" ";
cout<<endl;
system("pause");
}
void shell_sort(int a[], int n)
{
int gap;
for(gap = 3; gap >0; gap--)
{
for(int i=0; i<gap; i++)
{
for(int j = i+gap; j<n; j=j+gap)
{
if(a[j]<a[j-gap])
{
int temp = a[j];
int k = j-gap;
while(k>=0&&a[k]>temp)
{
a[k+gap] = a[k];
k = k-gap;
}
a[k+gap] = temp;
}
}
}
}
}
5.归并排序
将两个顺序序列合并成一个顺序序列的方法。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
/*该函数将数组下标范围[l1,r1]和[l2,r2]的有序序列合并成一个有序序列*/
void merge(vector<int>& nums, int l1, int r1, int l2, int r2 ) {
int i = l1; //左半部分起始位置
int j = l2; //右半部分起始位置
int n = (r1 - l1 + 1) + (r2 - l2 + 1); //要合并的元素个数
vector<int> temp(n); //辅助数组
int k = 0; //辅助数组其起始位置
while (i <= r1&&j <= r2) { //挑选两部分中最小的元素放入辅助数组中
if (nums[i] < nums[j])
temp[k++] = nums[i++];
else
temp[k++] = nums[j++];
}
//如果还有剩余,直接放入到辅助数组中
while (i <= r1)
temp[k++] = nums[i++];
while (j <= r2)
temp[k++] = nums[j++];
//更新原始数组元素
for (int i = 0; i < n;i++)
{
nums[l1 + i] = temp[i];
}
}
/*二路归并排序(递归实现)*/
void MergeSort(vector<int>& nums,int start, int end) {
if (start < end) {
int mid = (start + end) >> 1; //分割序列
MergeSort(nums, start, mid); //对序列左半部分进行规并排序
MergeSort(nums, mid + 1, end); //对序列右半部分进行规并排序
merge(nums, start, mid, mid + 1, end); //合并已经有序的两个序列
}
}
/*二路归并排序(迭代实现)*/
void MergeSort1(vector<int>& nums, int start, int end)
{
int n = nums.size();
if (start < end) {
//step为组内元素个数,step/2为左子区间元素个数
for (int step = 2; step/2 <n; step *= 2) {
//每step个元素一组,组内前step/2和后step/2个元素进行合并
for (int i = 0; i < n; i += step) {
int mid = i + step / 2 - 1; //左子区间元素个数为step/2
if(mid+1<n) //右子区间存在元素个数则合并
//左子区间为[i,mid],右子区间为[mid+1, min(i+step-1, n-1)]
merge(nums, i, mid, mid + 1, min(i + step - 1, n-1));
}
}
}
}
int main() {
vector<int> nums{ 1,4,3,2,5,6,3 };
MergeSort(nums,0,6);
// MergeSort1(nums, 0, 6);
for (auto x : nums)
cout << x << " ";
cout << endl;
return 0;
}
6.快速排序
首先任意选取一个数据(通常选用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。
#include <iostream>
using namespace std;
//exchange the 2 items a and b
void swap(int &a, int &b)
{
if (a == b)
return;
a = a + b;
b = a - b;
a = a - b;
}
//ergodic the buf and print it
void print(int *p, int length)
{
for (int i = 0; i < length; i++)
{
cout << p[i] << " ";
}
}
/*
quitSort
*/
int getPartion(int *array, int low, int high)
{
int key = array[low];
while (low < high)
{
while (low < high && key <= array[high]) //如果array[high]大于键值,那么本就应该在键值右边
high--; //因此将high下标向前移动,直至找到比键值小的值,此时交换这两个值
swap(array[low], array[high]);
while (low < high && key >= array[low])
low++;
swap(array[low], array[high]);
}
return low;//返回key值的下标
}
void QuitSort(int *buf,int low,int high)
{
if (low < high)
{
int key = getPartion(buf, low, high);
QuitSort(buf, low, key - 1);
QuitSort(buf, key + 1, high);
}
}
int main(int argc, char *args[])
{
int buf[10] = { 12, 4, 34, 6, 8, 65, 3, 2, 988, 45 };
int m = sizeof(buf);
cout << "排序前:" << endl;
print(buf, sizeof(buf) / sizeof(int));
QuitSort(buf, 0, sizeof(buf) / sizeof(int)-1);
cout << "\n\n\n排序后:" << endl;
print(buf, sizeof(buf) / sizeof(int));
getchar();
}