插入排序 :(直接插入排序,希尔排序)
交换排序:(起泡排序,快速排序)
选择排序:(简单选择排序,堆排序)
归并排序:
基数排序:
直接插入排序
*:
直接插入排序很简单。
基本思想是把第一个元素看成是一个有序数列,然后依次从第二个数据元素起逐个插入到有序数列中。将elem[i] 插入到elem[0]~slem[i-1]中.
#include<iostream>
#include<cstdio>
using namespace std;
const int N=35;
int a[N];
int main(){
for(int i=0;i<10;i++){ //插入十个无序的number
scanf("%d",&a[i]);
}
for(int i=1;i<=9;i++){
int e=a[i];
int j;
for( j=i-1;j>=0 && a[j]>e;j--){ //如果插入的数比与相比较的数小就继续循环,否则就停止
a[j+1]=a[j];
}
a[j+1]=e;
}
for(int i=0;i<10;i++){ //输出排序后的序列
printf("%d ",a[i]);
}
}
希尔排序:的基本思想是先将整个序列分割成若干的子序列,,然后再分别对子序列进行直接插入排序,最后在对整体进行一次插入排序。
设增量为d;(n为元素的总个数)
第一tang的个数为n/2;
第二趟的个数为n/4,依次递推******
一共需要多少趟的计算方法:
for(int i=0;;i++){
if(sun!=0){
sun=sun/2;
src[i]=sun;
num++;
}
else{
break;
}
}
num-1为所需要的趟数;
每一趟希尔排序需要进行多少次直接排序:
相邻的两个元素之间隔src:
这些都是需要注意的地方!
#include<iostream>
#include<cstdio>
using namespace std;
const int N=35;
int a[N];
int src[N];
void shellsort(int n,int src){
for(int i=src;i<n;i++){//每趟都进行直接排序
int e=a[i];
int j;
for( j=i-src;j>=0 && a[j]>e;j=j-src){
a[j+src]=a[j];
}
a[j+src]=e;
}
}
int main(){
int n;
int num=-1;
scanf("%d",&n);
int sun=n;
//求增量的方法
for(int i=0;;i++){
if(sun!=0){
sun=sun/2;
src[i]=sun;
num++;
}
else{
break;}
}
//输入数据
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
//进行希尔排序
for(int i=0;i<num;i++) {
shellsort(n,src[i]);
}
// 输入排序后的序列
for(int i=0;i<n;i++){
printf("%d ",a[i]);
}
}
起泡排序:
对于n个数排序,需要起泡n-1次,并且每次起泡是将最大的数字移动到数组的末端,
所以第i此排序需要比较的元素个数为:n-i;
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int b[15]
int main(){
int x;
scanf("%d",&x);
for(int i=0;i<x;i++){
scanf("%d",&b[i])
}
for(int i=0;i<x-1;i++){
for(int j=0;j<x-i;j++){
if(b[j]>b[j+1])
swap(b[j],b[j+1]);
}
}
for(int i=0;i<x;i++){
printf("%d",b[i]);
}
}
快速排序
选中枢(通常选取low为中枢的位置)
1.排好中枢的位置后,
排中枢的思想为把比中枢小的数放到左边,比中枢大的数放到右边。
2.排中枢左边,
3.排中枢右边
递归排序中枢左边,递归排序中枢右边,
直到low=high递归停止。
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[35];
int Control(int low,int high){
while(low<high){
while(low<high && a[high]>=a[low]){
high--;
}
swap(a[low],a[high]);
while(high>low && a[high]>=a[low]){
low++;
}
swap(a[low],a[high]);
}
return low;
}
int main(){
int x;
scanf("%d",&x);
for(int i=0;i<x;i++){
scanf("%d",&a[i]);
}
int low=0;
int high=x-1;
int sum=Control(low,high);
Control(low,sum-1);
Control(sum+1,high);
for(int i=0;i<x;i++){
printf("%d ",a[i]);
}
}
选择排序
简单的选择排序
主要思想:
第i趟是从第elem[i]----到elem[n-1]选择第i小的数并将元素放在elem[i]的位置上,也就是说从未排序的元素中找出最小的元素,放在排序的对列的最后边。
#include <iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int c1[15];
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&c1[i]);
}
//简单选择排序
for(int i=0;i<n-1;i++){ //n个元素需要进行n-1次简单选择排序
int lowindex=i;
for(int j=i+1;j<n;j++){
if(c1[lowindex]>c1[j]){
lowindex=j;
}
swap(c1[lowindex],c1[i]);
}
}
for(int i=0;i<n;i++){
printf("%d ",c1[i]);
}
}
堆排序排序算法
堆排序算法的步骤
1.把无序的序列变成大顶堆(小顶堆)(初始堆的建立)
我们要注意在这个过程中可以从第(n-2)/2个元素开始进行筛选,建立大顶堆。需要筛选(n-2)/2次
for(int i=(n-2)/2;i>=0;--i){ // 将无序的序列调整为大顶堆
SiftAdjust(i,n-1);
}
2.如果是大顶堆,并且从小到大输出排序序列,每次调换low,high的位置后,还应该对现在的堆进行排序,使它调整为新堆。
for(int i=n-1;i>0;--i){ //输出一个当前最大的元素后,还需要进行一次堆排序
swap(elem[0],elem[i]);
SiftAdjust(0,i-1);
}
这个图片是每次进行堆排序的过程!
#include <iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int elem[15];
void SiftAdjust(int low,int high){ //进行堆排序的算法
//elem[low]---elem[high]中的元素成为一个大顶堆
for(int f=low,i=low*2+1;i<=high;i=2*i+1){
if(i<high&&elem[i]<elem[i+1]){
i++;
}
if(elem[f]>=elem[i]){
//已经是大顶堆
break;
}
swap(elem[i],elem[f]);
f=i; //调整新的结点
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&elem[i]);
}
for(int i=(n-2)/2;i>=0;--i){ // 将无序的序列调整为大顶堆
SiftAdjust(i,n-1);
}
for(int i=n-1;i>0;--i){ //输出一个当前最大的元素后,还需要进行一次堆排序
swap(elem[0],elem[i]);
SiftAdjust(0,i-1);
}
for(int i=0;i<n;i++){
printf("%d ",elem[i]);
}
}