交换类算法:
起泡算法
每次选出一个最大的数字甩到后面,再次选择次大的,...循环下去。
#include <stdio.h>
//起泡排序
void BubbleSort(int R[],int n)
{
//大的数字往后冒(写小的往前也行)
int i,j,temp,flag=0;
//最大循环次数i,同时也用作限定每次内循环次数
for(i=n-1;i>0;i--)
{
//用来判断有无交换的标志flag
flag=0;
//每次起泡后,最后的元素一定是最大的且有序的,所以循环次数越来越少
for (j=1;j<=i; j++)
{
//大的数字往后交换
if(R[j-1]>R[j])
{
temp=R[j];
R[j]=R[j-1];
R[j-1]=temp;
flag=1;
}
}
//本轮无交换,则排序结束
if(flag==0)
return;
}
}
int main()
{
int a[7]{7,43,6,3,2,6,87};
BubbleSort(a, 7);
int i;
for(i=0;i<7;i++)
{
printf("%d ",a[i]);
}
}
快速排序
根据关键字划分子区间,左子区间小于关键字,右子区间大于关键字
#include <stdio.h>
//快速排序
void QuickSort(int R[],int low,int high)
{
int i=low,j=high;
int temp;
if(low<high)
{
//选择关键字
temp=R[low];
while(i<j)
{
//右边的往左扫描
//往左移动,找到一个比关键字小的,然后交换
while(j>i&&R[j]>=temp)
j--;
//如果重合的话就结束了,所以先判断
if(i<j)
{
R[i]=R[j];
//交换后往后移
i++;
}
//左边的往右扫描
//往右移动,找到一个比关键字大的,然后交换
while(j>i&&R[i]<temp)
i++;
//如果重合的话就结束了,所以先判断
if(i<j)
{
R[j]=R[i];
//交换后往后移
j--;
}
}
R[i]=temp;
//i,j重合时结束,将左区间和右区间继续进行快排
QuickSort(R, low, i-1);
QuickSort(R, i+1, high);
}
}
int main()
{
int a[7]{7,43,62,3,2,6,87};
QuickSort(a,0,6);
int i;
for(i=0;i<7;i++)
{
printf("%d ",a[i]);
}
}
选择类排序
简单选择排序
从头到尾扫描,选出最小的关键字与第一个元素交换,再选择第二个最小的关键字与第二个元素交换,...
(和起泡有点像哈)
#include <stdio.h>
//简单选择排序
void SelectSort(int R[],int n)
{
int i,j,k;
//交换三部曲的中间量
int temp;
for(i=0;i<n;i++)
{
//k为最靠前的未排序的关键字,内循环寻找最小值的起点
k=i;
for (j=i+1; j<n; j++) {
//选择最大值
if(R[k]>R[j])
k=j;
}
//交换三部曲
temp=R[i];
R[i]=R[k];
R[k]=temp;
}
}
int main()
{
int a[7]{7,43,62,3,2,6,87};
SelectSort(a,6);
int i;
for(i=0;i<7;i++)
{
printf("%d ",a[i]);
}
}
堆排序
#include <stdio.h>
//对low到high,进行调整
void Sift(int R[],int low,int high)
{
//R[j]是R[i]的左孩子
int i=low,j=2*i;
int temp=R[i];
while(j<=high)
{
//如果右孩子大,则j指向右孩子
//本质就是找左右孩子里最大的结点
if(j<high&&R[j]<R[j+1])
{
j++;
}
//如果最大结点大于双亲结点
if(temp<R[j])
{
R[i]=R[j];
//temp继续与原孩子结点的孩子结点继续比较
i=j;
j=2*i;
}
else
break;
}
//被调整的结点放在最后调整的位置
R[i]=temp;
}
//堆排序
void heapSort(int R[],int n)
{
int i;
int temp;
for(i=n/2;i>=1;i--)
Sift(R,i,n);
//以上所有的结点都符合大顶堆,但是排序还没完成,仅仅完成了建大堆的过程
//如果只剩下两个结点,顺序是必然的
for(i=n;i>=2;i--)
{
temp=R[1];
R[1]=R[i];
R[i]=temp;
Sift(R, 1, i-1);
}
}
int main()
{
//堆从1开始的99999只是占个坑
int a[8]{99999,7,43,62,3,2,6,87};
heapSort(a,6);
int i;
for(i=1;i<8;i++)
{
printf("%d ",a[i]);
}
}
二路归并排序
#include <stdio.h>
//对low到high,进行调整
void merge(int R[],int low ,int mid,int high)
{
//临时数组
int temp[1000];
int k=low;
int i=low,j=mid+1;
//小的先进入temp数组
for(i=low,j=mid+1;i<=mid,j<=high;)
{
if(R[i]<R[j])
{
temp[k++]=R[i];
i++;
}
else
{
temp[k++]=R[j];
j++;
}
}
//如果某一数组已经全部存完,对应数组直接进入数组
if(i==mid+1)
for(;j<=high;j++)
temp[k++]=R[j];
else if(j==high+1)
for(;i<=mid;i++)
temp[k++]=R[i];
//将temp的有序数组归还R数组
for(k=low;k<=high;k++)
R[k]=temp[k];
}
void mergeSort(int R[],int low,int high)
{
int i;
for(i=low;i<=high;i++)
{
printf("%d %d %d %d\n",i,R[i],low,high);
}
if(low<high)
{
int mid=(low+high)/2;
mergeSort(R,low,mid);
mergeSort(R,mid+1,high);
//1元组排序合并2元组,2元组排序合并4元组,...
merge(R,low,mid,high);
}
}
int main()
{
int a[7]{71,43,5,3,9,6};
mergeSort(a, 0, 5);
int i;
for(i=0;i<6;i++)
{
printf("%d ",a[i]);
}
}
桶排序
#include <stdio.h>
int pow(int i)
{
if(i==0)
return 1;
if(i==1)
return 10;
if(i==2)
return 100;
if(i==3)
return 1000;
return 1;
}
void tong(int a[100],int n,int sum)
{
int B[100];
int i,j,k;
int flag=0;
//最高位为n为,本次测试为3位
for (i=0;i<n;i++)
{
//每个数组共十个特征,即0-9
for(j=0;j<10;j++)
{
//对位置进行筛选(本过程直接类似出桶)
for(k=0;k<sum;k++)
{
if((a[k]/pow(i))%10==j)
B[flag++]=a[k];
}
}
//更换标志位
flag=0;
//更新桶
for(k=0;k<sum;k++)
{
a[k]=B[k];
}
}
}
int main()
{
int a[100]={232,41,34,7,58,9,5,424,145,1};
tong(a,3,10);
}