1,选择排序
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
for(int i=0;i<10;i++)
{
int index=i;
for(int j=i+1;j<10;j++)
{
if(a[j]<a[index])
{
index=j; //找到I位置以后的最小数字对应的下标
}
}
if(i!=index) //如果当前位置不满足要求,也就是说后面的数字中有比当前数字小的数字存在,就进行交换
{
int temp=a[i];
a[i]=a[index];
a[index]=temp;
}
}
}
int main()
{
solve();
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
2,插入排序
理解:执行第i次循环的时候,默认的是0~i-1这个区间内的数字已经有序,然后用第i个位置的数字去与这些区间内的数字进行比较。比较的过程类似于冒泡。
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
for(int i=0;i<10;i++)
{
for(int j=i-1;j>=0;j--)
{
if(a[j+1]<a[j])
swap(a[j+1],a[j]); //本质上就是用i位置的数字去跟0~i-1之间内数字进行比较,如果a[i]小,那就直接就换。
else
break;
}
}
}
int main()
{
solve();
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
3,冒泡排序
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,5,6,1,9,8,7};
//默认升序排序
void solve()
{
for(int i=0;i<10;i++)
{
for(int j=0;j<10-i-1;j++)
{
if(a[j]>a[j+1])
{
swap(a[j],a[j+1]); //大的数字往后移动
}
}
}
}
int main()
{
solve();
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
4,希尔排序
理解:通过对数组进行分组,对每一个分组进行插入排序,这样的算法复杂度有所提高。
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100]; //辅助数组,用来存储子数组
//默认升序排序
void solve()
{
int len=10;
int dis=10;
do
{
dis=dis/3+1; //设置的划分组数的大小
for(int i=0;i<len;i++)
{
int index=0;
for(int j=i;j<len;j+=dis)
{
b[index++]=a[j];
}
//使用插入排序对b[]进行排序
for(int k=0;k<index;k++)
{
for(int j=k-1;j>=0;j--)
{
if(b[j+1]<b[j])
swap(b[j+1],b[j]);
else
break;
}
}
index=0;
//将排好序的子数组复制到原数组当中
for(int j=i;j<len;j+=dis)
{
a[j]=b[index++];
}
}
}while(dis>1); //当划分的组的大小为1的时候,排序结束。
}
int main()
{
solve();
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
5,归并排序
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];//辅助数组
int len=10;
//默认升序排序
void mergsort(int l,int mid,int r)
{
int i=l;
int j=mid+1;
int index=0;
while(i<=mid&&j<=r)
{
if(a[i]<a[j])
b[index++]=a[i++];
else
b[index++]=a[j++];
}
while(i<=mid)
{
b[index++]=a[i++];
}
while(j<=r)
{
b[index++]=a[j++];
}
index=0;
for(int i=l;i<=r;i++) //把排好序的子数组复制到原数组中
{
a[i]=b[index++];
}
}
void solve(int l,int r)
{
if(l<r)
{
solve(l,(l+r)>>1), //划分左区间
solve(((l+r)>>1)+1,r); //划分右区间
mergsort(l,(l+r)>>1,r); //对左右区间进行排序
}
}
int main()
{
solve(0,9);
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
6,快速排序
理解:快排没排序一次,就确定了一个数字最终的位置。
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];
int len=10;
int mergesort(int l,int r)
{
int i=l;
int j=r;
int val=a[l];
while(i<j)
{
while(a[j]>=val&&j>i) //从后往前找到一个比a[l]小的数字
j--;
a[i]=a[j];
while(a[i]<=val&&i<j) //从前往收找到一个比a[l]大的数字
i++;
a[j]=a[i]; //交换
}
a[i]=val;
return i;
}
void solve(int l,int r)
{
if(l<r)
{
int pos=mergesort(l,r);
//cout<<pos<<endl;
solve(l,pos-1); //对于快排来说,每排序一次,就确定了一个数字最终的位置
solve(pos+1,r);
}
}
int main()
{
solve(0,9);
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
return 0;
}
7,堆排序
理解:大顶堆对应着升序,反之小顶堆对应着降序。
#include <bits/stdc++.h>
using namespace std;
int a[10]={0,3,2,4,6,5,9,1,8,7};
int b[100];
int len=10;
void res(int x,int length)
{
int temp=a[x];
for(int k=x*2+1;k<length;k=k*2+1) //此处的k=k*2+1解析:有人会有疑问:就是在程序中如果右节点比左节点大的话,那么k就++,然后此处有k=k*2+1,那么左子树下的节点就不管了吗?答案是肯定的,你可以从最初构造大顶堆的过程中看,他是从下往上构造的,这个性质就决定了如果当前左子树节点比右子树节点小的话,就没有必要遍历左子树下的节点了。你可以画一下就知道了。
{
if(a[k]<a[k+1]&&(k+1)<length) //如果右孩子比左孩子大,由于是大顶堆所以是右节点
k++;
if(a[k]>temp)
{
a[x]=a[k];
x=k;
}
else
break; //如果两个孩子都没有父亲节节点大的话,就没有必要在进行遍历左右子树了。因为构造是从下往上构造的。
}
a[x]=temp;
}
void out()
{
for(int i=0;i<10;i++)
{
cout<<a[i]<<" ";
}
}
void solve(int l,int r)
{
for(int i=len/2-1;i>=0;i--)
res(i,len); //调整堆,使其最终成为大顶堆
//out();
//cout<<"****"<<endl;
for(int i=len-1;i>0;i--)
{
swap(a[0],a[i]); //每交换一次都要进行堆调整
//out();
//cout<<endl;
res(0,i);
//out();
//cout<<endl;
}
}
int main()
{
solve(0,9);
out();
return 0;
}
8,计数排序
计数排序的基本思想为一组数在排序之前先统计这组数中其他数小于这个数的个数,则可以确定这个数的位置。例如要排序的数为 7 4 2 1 5 3 1 5;则比7小的有7个数,所有7应该在排序好的数列的第八位,同理3在第四位,对于重复的数字,1在1位和2位(暂且认为第一个1比第二个1小),5和1一样位于6位和7位。
#include <bits/stdc++.h>
using namespace std;
int a[10]= {0,3,2,4,6,5,9,1,8,7};
int sum[100];
int len=10;
void out()
{
for(int i=0; i<10; i++)
{
cout<<a[i]<<" ";
}
}
void solve()
{
int c[100];
int maxn=-1;
for(int i=0; i<len; i++)
{
maxn=max(a[i],maxn); //找到最大值,目的为了开辟b数组的空间
}
//cout<<maxn<<endl;
int b[maxn*2];
memset(b,0,sizeof(b));
for(int i=0; i<len; i++)
{
b[a[i]]++; //统计每个数字的次数
}
for(int i=0; i<maxn+1; i++)
{
if(i==0) continue;
b[i]=b[i]+b[i-1]; //统计数组中的数字比其小的数字的个数。
}
for(int i=0;i<len;i++)
{
b[a[i]]--; //下标从0开始所以要 -1
c[b[a[i]]]=a[i]; //c数组是个辅助数组。
}
for(int i=0;i<len;i++)
a[i]=c[i];
}
int main()
{
solve();
out();
return 0;
}
9,桶排序
后续更新。
10,基数排序
理解:就是把数组中的数字按个位,十位...最高位,每次按位去比较数组中的数字。
#include <bits/stdc++.h>
using namespace std;
void printArray(int array[],int length)
{
for (int i = 0; i < length; ++i)
{
cout << array[i] << " ";
}
cout << endl;
}
int maxbit(int data[], int n)
{
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[n];
int count[10];
int i, j, k;
int radix = 1;
for(i = 1; i <= d; i++)
{
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];
for(j = n - 1; j >= 0; j--)
{
k = (data[j] / radix) % 10;
tmp[count[k] - 1] = data[j];
count[k]--;
}
for(j = 0; j < n; j++)
data[j] = tmp[j];
radix = radix * 10;
}
}
int main()
{
int array[10] = {0,2,3,6,9,1,4,5,7,8};
radixsort(array,10);
printArray(array,10);
return 0;
}