各种排序的过程
实现各种排序算法,同时输出每次主要的操作时数组状态
1.冒泡
2.选择
3.插入
4.快速排序
5.堆排序
6.归并排序
7.希尔排序
8.基数排序
(基数排序一般链表实现,这里没做)
显示每次主要操作后的结果,旁边的两个数字显示了有关信息,具体是什么看代码前的注释
如果用移动优化了交换,中间结果可能有重复
源代码
#include<iostream>
#include<stdio.h>
using namespace std;
//在这里改变待待排序数据
int source[]={5,8,3,4,9,6,1,2,7,0};
//每次改变数据,需要修改数据个数!!!
int count=10;
//输出数组中全部数据
void Show(int data[]){
for(int i=0;i<count;i++){
cout<<data[i]<<" ";
}cout<<endl<<endl;
}
//输出数组中全部数据,带标志显示
void Show(int data[],int x,int y){
for(int i=0;i<count;i++){
cout<<data[i]<<" ";
}
printf(" ( %d<-->%d )\n",x,y) ;
}
void Copy(int data[],int target[],int size){
for(int i=0;i<size;i++){
target[i]=data[i];
}
}
void Swap(int &a,int &b){
int temp = a;
a=b;b=temp;
}
//冒泡排序
//每次交换相邻两个元素
//标识为每次排序比较的两个数
void Sort1(int data[],int size){
cout<<"--------------冒泡排序--------------"<<endl;
for(int i=0;i<size-1;i++){
for(int j=0;j<size-i-1;j++){
Show(data,data[j],data[j+1]);
if(data[j]>data[j+1]){
int temp = data[j];
data[j] = data[j+1];
data[j+1] = temp;
}
}
}
}
//选择排序
//遍历找到未排序区最小,然后放到已排序区后面
//标识为每次交换的两个数
void Sort2(int data[],int size){
cout<<"--------------选择排序--------------"<<endl;
for(int i=0;i<size-1;i++){
//遍历未排序,找出最小的数
int min=i;//min是最小的数的索引
for(int j=i+1;j<size;j++){
if(data[min]>data[j]){
min=j;
}
}
//最小数与已排区域后面第一个元素交换位置
Show(data,data[i],data[min]);
Swap(data[min],data[i]);
}
}
//插入排序
//每次将一个元素插入已排序区域相应位置
//标识为每次插入交换的两个数(移动式,中间可能有没变的)
void Sort3(int data[],int size){
cout<<"--------------插入排序--------------"<<endl;
for(int i=1;i<size;i++){
int temp=data[i];
int j=i-1;
//把已排区域后第一个数插入到已排区域
//这里做了优化,交换次数少了
while(j>=0&&data[j]>temp){
Show(data,data[j+1],data[j]);
data[j+1]=data[j];
j--;
}
Show(data,temp,data[j+1]);
data[j+1]=temp;
}
}
//快速排序
//选择一个枢轴点,把小于它的放左边,大于他的放右边
//然后对左右两边继续应用快速排序
//标识为本次快排区间
void Sort4fun(int data[],int left,int right){
//当左已经大于或等于右,最多只有一个元素,不用排序了
if(left>=right)return;
Show(data,left,right);
//选择区域中第一个数作为枢轴
int choice = data[left];
int i=left,j=right;
while(i<j){
//从右向左找比枢轴小的,保存到前面
while(i<j&&choice<data[j]){j--;}
if(i<j){data[i]=data[j];i++;}
//从左往右找比枢轴大的,保存到后面
while(i<j&&choice>data[i]){i++;}
if(i<j){data[j]=data[i];j--;}
}
//最终,左右标志重合,这个位置就是枢轴存的位置
data[i]=choice;
//对枢轴两侧的元素分别调用快速排序
Sort4fun(data,i+1,right);
Sort4fun(data,left,i-1);
}
void Sort4(int data[],int size){
cout<<"--------------快速排序--------------"<<endl;
Sort4fun(data,0,size-1);
}
//堆排序
//将数组视为完全二叉树,把他调整为一个堆,
//依次对换第一个元素和最后一个元素,并调整堆。
//标识为本次交换的数
void Sort5fun(int data[],int target,int size){
//调整堆
int left = target*2+1;
int right = target*2+2;
//如果左节点都不存在,那么它没有子节点可以直接退出
if(left>=size)return;
//选择左右节点中最大的
int max = left;
//如果没有右节点,只判断是否需要与左交换即可
if(right<size&&data[max]<data[right]){
max=right;
}
//如果左右节点中最大的大于自己,交换并继续调整这个子节点
//否则堆已经成立,调整结束
if(data[max]>data[target]){
Show(data,data[max],data[target]);
Swap(data[max],data[target]);
查看每次排序交换的元素
// printf("Swap {[%d]=%d} , {[%d]=%d}\n"
// ,max,data[max],target,data[target]);
Sort5fun(data,max,size);
}
}
//堆其实就是一个以数组方式存储的完全二叉树
//对于节点i,左子节点为2*i+1,右子节点为2*i+2
void Sort5(int data[],int size){
cout<<"--------------堆排序--------------"<<endl;
//建堆
for(int i=size-1;i>=0;i--){
Sort5fun(data,i,size);
}
//调整
for(int i=size-1;i>0;i--){
Show(data,data[i],data[0]);
Swap(data[i],data[0]);
Sort5fun(data,0,i);
}
}
//归并排序
//把数组逐渐分解为小区间,对每两个个小区间使用
//合并有序数组算法,最终合并为一个
//需要使用o(n)空间
//标识为本次排序左右边界
void Sort6fun(int data[],int left,int right,int temp[]){
if(left>=right)return;
//将数据分为两个组
int mid=(left+right)/2;
Sort6fun(data,left,mid,temp);
Sort6fun(data,mid+1,right,temp);
//执行两路归并
int i=left,j=mid+1,k=left;
while(i<=mid&&j<=right){
if(data[i]<data[j]){
temp[k]=data[i];
k++;i++;
}else{
temp[k]=data[j];
k++;j++;
}
}
//最后可能有一些数据没有加入
while(i<=mid){
temp[k]=data[i];k++;i++;
}
while(j<=right){
temp[k]=data[j];k++;j++;
}
//两路归并完成,数据复制到原数组中
Show(data,left,right);
k=left;
while(k<=right){
data[k]=temp[k];
k++;
}
}
void Sort6(int data[],int size){
cout<<"--------------归并排序--------------"<<endl;
int temp[size];
Sort6fun(data,0,size-1,temp);
}
//希尔排序
//间隔若干元素的视为一组,应用插入排序,
//然后减少间隔,直到间隔达到1
//gap为size/2,以后每次都除2
//标识为本次移动的数
void Sort7(int data[],int size){
cout<<"--------------希尔排序--------------"<<endl;
//控制gap增量
for(int gap=size/2;gap>0;gap/=2){
//对每个分组执行插入排序
for(int n=0;n<gap;n++){
//内部的插入排序
for(int i=n+gap;i<size;i+=gap){
int j=i-gap,temp=data[i];
while(0<=j&&temp<data[j]){
Show(data,data[j+gap],data[j]);
data[j+gap]=data[j];
j-=gap;
}
data[j+gap]=temp;
}
}
}
}
int main(){
int data[count];
Copy(source,data,count);
Sort1(data,count);
Show(data);
Copy(source,data,count);
Sort2(data,count);
Show(data);
Copy(source,data,count);
Sort3(data,count);
Show(data);
Copy(source,data,count);
Sort4(data,count);
Show(data);
Copy(source,data,count);
Sort5(data,count);
Show(data);
Copy(source,data,count);
Sort6(data,count);
Show(data);
Copy(source,data,count);
Sort7(data,count);
Show(data);
return 0;
}
运行效果:
--------------冒泡排序--------------
5 8 3 4 9 6 1 2 7 0 ( 5<-->8 )
5 8 3 4 9 6 1 2 7 0 ( 8<-->3 )
5 3 8 4 9 6 1 2 7 0 ( 8<-->4 )
5 3 4 8 9 6 1 2 7 0 ( 8<-->9 )
5 3 4 8 9 6 1 2 7 0 ( 9<-->6 )
5 3 4 8 6 9 1 2 7 0 ( 9<-->1 )
5 3 4 8 6 1 9 2 7 0 ( 9<-->2 )
5 3 4 8 6 1 2 9 7 0 ( 9<-->7 )
5 3 4 8 6 1 2 7 9 0 ( 9<-->0 )
5 3 4 8 6 1 2 7 0 9 ( 5<-->3 )
3 5 4 8 6 1 2 7 0 9 ( 5<-->4 )
3 4 5 8 6 1 2 7 0 9 ( 5<-->8 )
3 4 5 8 6 1 2 7 0 9 ( 8<-->6 )
3 4 5 6 8 1 2 7 0 9 ( 8<-->1 )
3 4 5 6 1 8 2 7 0 9 ( 8<-->2 )
3 4 5 6 1 2 8 7 0 9 ( 8<-->7 )
3 4 5 6 1 2 7 8 0 9 ( 8<-->0 )
3 4 5 6 1 2 7 0 8 9 ( 3<-->4 )
3 4 5 6 1 2 7 0 8 9 ( 4<-->5 )
3 4 5 6 1 2 7 0 8 9 ( 5<-->6 )
3 4 5 6 1 2 7 0 8 9 ( 6<-->1 )
3 4 5 1 6 2 7 0 8 9 ( 6<-->2 )
3 4 5 1 2 6 7 0 8 9 ( 6<-->7 )
3 4 5 1 2 6 7 0 8 9 ( 7<-->0 )
3 4 5 1 2 6 0 7 8 9 ( 3<-->4 )
3 4 5 1 2 6 0 7 8 9 ( 4<-->5 )
3 4 5 1 2 6 0 7 8 9 ( 5<-->1 )
3 4 1 5 2 6 0 7 8 9 ( 5<-->2 )
3 4 1 2 5 6 0 7 8 9 ( 5<-->6 )
3 4 1 2 5 6 0 7 8 9 ( 6<-->0 )
3 4 1 2 5 0 6 7 8 9 ( 3<-->4 )
3 4 1 2 5 0 6 7 8 9 ( 4<-->1 )
3 1 4 2 5 0 6 7 8 9 ( 4<-->2 )
3 1 2 4 5 0 6 7 8 9 ( 4<-->5 )
3 1 2 4 5 0 6 7 8 9 ( 5<-->0 )
3 1 2 4 0 5 6 7 8 9 ( 3<-->1 )
1 3 2 4 0 5 6 7 8 9 ( 3<-->2 )
1 2 3 4 0 5 6 7 8 9 ( 3<-->4 )
1 2 3 4 0 5 6 7 8 9 ( 4<-->0 )
1 2 3 0 4 5 6 7 8 9 ( 1<-->2 )
1 2 3 0 4 5 6 7 8 9 ( 2<-->3 )
1 2 3 0 4 5 6 7 8 9 ( 3<-->0 )
1 2 0 3 4 5 6 7 8 9 ( 1<-->2 )
1 2 0 3 4 5 6 7 8 9 ( 2<-->0 )
1 0 2 3 4 5 6 7 8 9 ( 1<-->0 )
0 1 2 3 4 5 6 7 8 9
--------------选择排序--------------
5 8 3 4 9 6 1 2 7 0 ( 5<-->0 )
0 8 3 4 9 6 1 2 7 5 ( 8<-->1 )
0 1 3 4 9 6 8 2 7 5 ( 3<-->2 )
0 1 2 4 9 6 8 3 7 5 ( 4<-->3 )
0 1 2 3 9 6 8 4 7 5 ( 9<-->4 )
0 1 2 3 4 6 8 9 7 5 ( 6<-->5 )
0 1 2 3 4 5 8 9 7 6 ( 8<-->6 )
0 1 2 3 4 5 6 9 7 8 ( 9<-->7 )
0 1 2 3 4 5 6 7 9 8 ( 9<-->8 )
0 1 2 3 4 5 6 7 8 9
--------------插入排序--------------
5 8 3 4 9 6 1 2 7 0 ( 8<-->8 )
5 8 3 4 9 6 1 2 7 0 ( 3<-->8 )
5 8 8 4 9 6 1 2 7 0 ( 8<-->5 )
5 5 8 4 9 6 1 2 7 0 ( 3<-->5 )
3 5 8 4 9 6 1 2 7 0 ( 4<-->8 )
3 5 8 8 9 6 1 2 7 0 ( 8<-->5 )
3 5 5 8 9 6 1 2 7 0 ( 4<-->5 )
3 4 5 8 9 6 1 2 7 0 ( 9<-->9 )
3 4 5 8 9 6 1 2 7 0 ( 6<-->9 )
3 4 5 8 9 9 1 2 7 0 ( 9<-->8 )
3 4 5 8 8 9 1 2 7 0 ( 6<-->8 )
3 4 5 6 8 9 1 2 7 0 ( 1<-->9 )
3 4 5 6 8 9 9 2 7 0 ( 9<-->8 )
3 4 5 6 8 8 9 2 7 0 ( 8<-->6 )
3 4 5 6 6 8 9 2 7 0 ( 6<-->5 )
3 4 5 5 6 8 9 2 7 0 ( 5<-->4 )
3 4 4 5 6 8 9 2 7 0 ( 4<-->3 )
3 3 4 5 6 8 9 2 7 0 ( 1<-->3 )
1 3 4 5 6 8 9 2 7 0 ( 2<-->9 )
1 3 4 5 6 8 9 9 7 0 ( 9<-->8 )
1 3 4 5 6 8 8 9 7 0 ( 8<-->6 )
1 3 4 5 6 6 8 9 7 0 ( 6<-->5 )
1 3 4 5 5 6 8 9 7 0 ( 5<-->4 )
1 3 4 4 5 6 8 9 7 0 ( 4<-->3 )
1 3 3 4 5 6 8 9 7 0 ( 2<-->3 )
1 2 3 4 5 6 8 9 7 0 ( 7<-->9 )
1 2 3 4 5 6 8 9 9 0 ( 9<-->8 )
1 2 3 4 5 6 8 8 9 0 ( 7<-->8 )
1 2 3 4 5 6 7 8 9 0 ( 0<-->9 )
1 2 3 4 5 6 7 8 9 9 ( 9<-->8 )
1 2 3 4 5 6 7 8 8 9 ( 8<-->7 )
1 2 3 4 5 6 7 7 8 9 ( 7<-->6 )
1 2 3 4 5 6 6 7 8 9 ( 6<-->5 )
1 2 3 4 5 5 6 7 8 9 ( 5<-->4 )
1 2 3 4 4 5 6 7 8 9 ( 4<-->3 )
1 2 3 3 4 5 6 7 8 9 ( 3<-->2 )
1 2 2 3 4 5 6 7 8 9 ( 2<-->1 )
1 1 2 3 4 5 6 7 8 9 ( 0<-->1 )
0 1 2 3 4 5 6 7 8 9
--------------快速排序--------------
5 8 3 4 9 6 1 2 7 0 ( 0<-->9 )
0 2 3 4 1 5 6 9 7 8 ( 6<-->9 )
0 2 3 4 1 5 6 9 7 8 ( 7<-->9 )
0 2 3 4 1 5 6 8 7 9 ( 7<-->8 )
0 2 3 4 1 5 6 7 8 9 ( 0<-->4 )
0 2 3 4 1 5 6 7 8 9 ( 1<-->4 )
0 1 2 4 3 5 6 7 8 9 ( 3<-->4 )
0 1 2 3 4 5 6 7 8 9
--------------堆排序--------------
5 8 3 4 9 6 1 2 7 0 ( 7<-->4 )
5 8 3 7 9 6 1 2 4 0 ( 6<-->3 )
5 8 6 7 9 3 1 2 4 0 ( 9<-->8 )
5 9 6 7 8 3 1 2 4 0 ( 9<-->5 )
9 5 6 7 8 3 1 2 4 0 ( 8<-->5 )
9 8 6 7 5 3 1 2 4 0 ( 0<-->9 )
0 8 6 7 5 3 1 2 4 9 ( 8<-->0 )
8 0 6 7 5 3 1 2 4 9 ( 7<-->0 )
8 7 6 0 5 3 1 2 4 9 ( 4<-->0 )
8 7 6 4 5 3 1 2 0 9 ( 0<-->8 )
0 7 6 4 5 3 1 2 8 9 ( 7<-->0 )
7 0 6 4 5 3 1 2 8 9 ( 5<-->0 )
7 5 6 4 0 3 1 2 8 9 ( 2<-->7 )
2 5 6 4 0 3 1 7 8 9 ( 6<-->2 )
6 5 2 4 0 3 1 7 8 9 ( 3<-->2 )
6 5 3 4 0 2 1 7 8 9 ( 1<-->6 )
1 5 3 4 0 2 6 7 8 9 ( 5<-->1 )
5 1 3 4 0 2 6 7 8 9 ( 4<-->1 )
5 4 3 1 0 2 6 7 8 9 ( 2<-->5 )
2 4 3 1 0 5 6 7 8 9 ( 4<-->2 )
4 2 3 1 0 5 6 7 8 9 ( 0<-->4 )
0 2 3 1 4 5 6 7 8 9 ( 3<-->0 )
3 2 0 1 4 5 6 7 8 9 ( 1<-->3 )
1 2 0 3 4 5 6 7 8 9 ( 2<-->1 )
2 1 0 3 4 5 6 7 8 9 ( 0<-->2 )
0 1 2 3 4 5 6 7 8 9 ( 1<-->0 )
1 0 2 3 4 5 6 7 8 9 ( 0<-->1 )
0 1 2 3 4 5 6 7 8 9
--------------归并排序--------------
5 8 3 4 9 6 1 2 7 0 ( 0<-->1 )
5 8 3 4 9 6 1 2 7 0 ( 0<-->2 )
3 5 8 4 9 6 1 2 7 0 ( 3<-->4 )
3 5 8 4 9 6 1 2 7 0 ( 0<-->4 )
3 4 5 8 9 6 1 2 7 0 ( 5<-->6 )
3 4 5 8 9 1 6 2 7 0 ( 5<-->7 )
3 4 5 8 9 1 2 6 7 0 ( 8<-->9 )
3 4 5 8 9 1 2 6 0 7 ( 5<-->9 )
3 4 5 8 9 0 1 2 6 7 ( 0<-->9 )
0 1 2 3 4 5 6 7 8 9
--------------希尔排序--------------
5 8 3 4 9 6 1 2 7 0 ( 1<-->8 )
5 1 3 4 9 6 8 2 7 0 ( 2<-->3 )
5 1 2 4 9 6 8 3 7 0 ( 0<-->9 )
5 1 2 4 0 6 8 3 7 9 ( 2<-->5 )
2 1 5 4 0 6 8 3 7 9 ( 0<-->5 )
2 1 5 4 5 6 8 3 7 9 ( 5<-->2 )
0 1 2 4 5 6 8 3 7 9 ( 7<-->8 )
0 1 2 4 5 6 7 3 8 9 ( 3<-->6 )
0 1 2 4 5 6 7 6 8 9 ( 6<-->4 )
0 1 2 3 5 4 7 6 8 9 ( 4<-->5 )
0 1 2 3 4 5 7 6 8 9 ( 6<-->7 )
0 1 2 3 4 5 6 7 8 9