复习一下各种排序算法

 

复习一下各种排序算法
1.冒泡
2.选择
3.插入
4.快速排序
5.堆排序
6.归并排序
7.希尔排序 
8.基数排序

有个博客讲原理讲的挺好的:
https://www.cnblogs.com/chengxiao/p/6104371.html

冒泡排序 
每次交换相邻两个元素 

------冒泡排序------
5 8 3 4 9 6 1 2 7 0
5 3 4 8 6 1 2 7 0 9
3 4 5 6 1 2 7 0 8 9
3 4 5 1 2 6 0 7 8 9
3 4 1 2 5 0 6 7 8 9
3 1 2 4 0 5 6 7 8 9
1 2 3 0 4 5 6 7 8 9
1 2 0 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
void Sort1(int data[],int size){
    cout<<"------冒泡排序------"<<endl;
    for(int i=0;i<size-1;i++){
        Show(data);
        for(int j=0;j<size-i-1;j++){
            if(data[j]>data[j+1]){
                int temp = data[j];
                data[j] = data[j+1];
                data[j+1] = temp;
            }
        }
    }
}

选择排序
遍历找到未排序区最小,然后放到已排序区后面

------选择排序------
5 8 3 4 9 6 1 2 7 0
0 8 3 4 9 6 1 2 7 5
0 1 3 4 9 6 8 2 7 5
0 1 2 4 9 6 8 3 7 5
0 1 2 3 9 6 8 4 7 5
0 1 2 3 4 6 8 9 7 5
0 1 2 3 4 5 8 9 7 6
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 7 9 8
0 1 2 3 4 5 6 7 8 9

void Sort2(int data[],int size){
    cout<<"------选择排序------"<<endl;
    for(int i=0;i<size-1;i++){
        Show(data);
        //遍历未排序,找出最小的数 
        int min=i;//min是最小的数的索引 
        for(int j=i+1;j<size;j++){
            if(data[min]>data[j]){
                min=j;
            }
        }
        //最小数与已排区域后面第一个元素交换位置 
        Swap(data[min],data[i]); 
    }
}

 

插入排序
每次将一个元素插入已排序区域相应位置

------插入排序------
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
3 5 8 4 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 6 8 9 1 2 7 0
1 3 4 5 6 8 9 2 7 0
1 2 3 4 5 6 8 9 7 0
1 2 3 4 5 6 7 8 9 0
0 1 2 3 4 5 6 7 8 9

void Sort3(int data[],int size){
    cout<<"------插入排序------"<<endl;
    for(int i=1;i<size;i++){
        Show(data);
        int temp=data[i];
        int j=i-1;
        //把已排区域后第一个数插入到已排区域 
        //这里做了优化,交换次数少了 
        while(j>=0&&data[j]>temp){
            data[j+1]=data[j];
            j--;
        }
        data[j+1]=temp;
    }
} 

 


 

快速排序
选择一个枢轴点,把小于它的放左边,大于他的放右边
然后对左右两边继续应用快速排序

------快速排序------
5 8 3 4 9 6 1 2 7 0
0 2 3 4 1 5 6 9 7 8
0 2 3 4 1 5 6 9 7 8
0 1 2 4 3 5 6 9 7 8
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 8 7 9
0 1 2 3 4 5 6 7 8 9

void Sort4fun(int data[],int left,int right){
    //当左已经大于或等于右,最多只有一个元素,不用排序了 
    if(left>=right)return;
    Show(data);
    //选择区域中第一个数作为枢轴 
    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);
}

 

堆排序
将数组视为完全二叉树,把他调整为一个堆,
依次对换第一个元素和最后一个元素,并调整堆。

------堆排序--------
5 8 3 4 9 6 1 2 7 0
9 8 6 7 5 3 1 2 4 0
8 7 6 4 5 3 1 2 0 9
7 5 6 4 0 3 1 2 8 9
6 5 3 4 0 2 1 7 8 9
5 4 3 1 0 2 6 7 8 9
4 2 3 1 0 5 6 7 8 9
3 2 0 1 4 5 6 7 8 9
2 1 0 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9

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]){
        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;
    Show(data);
    //建堆 
    for(int i=size-1;i>=0;i--){
        Sort5fun(data,i,size);
    }
    
    //调整 
    for(int i=size-1;i>0;i--){
        Show(data);
        Swap(data[i],data[0]);
        Sort5fun(data,0,i);
    }
} 

 

归并排序
把数组逐渐分解为小区间,对每两个个小区间使用
合并有序数组算法,最终合并为一个

------归并排序------
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
3 5 8 4 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 1 2 6 7 0
0 1 2 3 4 5 6 7 8 9

void Sort6fun(int data[],int left,int right,int temp[]){
    if(left>=right)return;
    Show(data); 
    
    //将数据分为两个组 
    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++;
    }
    
    //两路归并完成,数据复制到原数组中 
    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

------希尔排序------
5 8 3 4 9 6 1 2 7 0
5 1 2 4 0 6 8 3 7 9
0 1 2 3 5 4 7 6 8 9
0 1 2 3 4 5 6 7 8 9

void Sort7(int data[],int size){
    cout<<"------希尔排序------"<<endl;
    for(int gap=size/2;gap>0;gap/=2){
        Show(data); 
        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]){
                    data[j+gap]=data[j];
                    j-=gap;
                }
                data[j+gap]=temp;
            }
        }
    }
}

 

/*
实现各种排序算法
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;
}
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;
} 

//冒泡排序 
//每次交换相邻两个元素 
/*
------冒泡排序------
5 8 3 4 9 6 1 2 7 0
5 3 4 8 6 1 2 7 0 9
3 4 5 6 1 2 7 0 8 9
3 4 5 1 2 6 0 7 8 9
3 4 1 2 5 0 6 7 8 9
3 1 2 4 0 5 6 7 8 9
1 2 3 0 4 5 6 7 8 9
1 2 0 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/
void Sort1(int data[],int size){
    cout<<"------冒泡排序------"<<endl;
    for(int i=0;i<size-1;i++){
        Show(data);
        for(int j=0;j<size-i-1;j++){
            if(data[j]>data[j+1]){
                int temp = data[j];
                data[j] = data[j+1];
                data[j+1] = temp;
            }
        }
    }
}

//选择排序 
//遍历找到未排序区最小,然后放到已排序区后面 
/*
------选择排序------
5 8 3 4 9 6 1 2 7 0
0 8 3 4 9 6 1 2 7 5
0 1 3 4 9 6 8 2 7 5
0 1 2 4 9 6 8 3 7 5
0 1 2 3 9 6 8 4 7 5
0 1 2 3 4 6 8 9 7 5
0 1 2 3 4 5 8 9 7 6
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 7 9 8
0 1 2 3 4 5 6 7 8 9
*/ 
void Sort2(int data[],int size){
    cout<<"------选择排序------"<<endl;
    for(int i=0;i<size-1;i++){
        Show(data);
        //遍历未排序,找出最小的数 
        int min=i;//min是最小的数的索引 
        for(int j=i+1;j<size;j++){
            if(data[min]>data[j]){
                min=j;
            }
        }
        //最小数与已排区域后面第一个元素交换位置 
        Swap(data[min],data[i]); 
    }
}

//插入排序
//每次将一个元素插入已排序区域相应位置 
/*
------插入排序------
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
3 5 8 4 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 6 8 9 1 2 7 0
1 3 4 5 6 8 9 2 7 0
1 2 3 4 5 6 8 9 7 0
1 2 3 4 5 6 7 8 9 0
0 1 2 3 4 5 6 7 8 9
*/ 
void Sort3(int data[],int size){
    cout<<"------插入排序------"<<endl;
    for(int i=1;i<size;i++){
        Show(data);
        int temp=data[i];
        int j=i-1;
        //把已排区域后第一个数插入到已排区域 
        //这里做了优化,交换次数少了 
        while(j>=0&&data[j]>temp){
            data[j+1]=data[j];
            j--;
        }
        data[j+1]=temp;
    }
} 


//快速排序 
//选择一个枢轴点,把小于它的放左边,大于他的放右边
//然后对左右两边继续应用快速排序 
/*
------快速排序------
5 8 3 4 9 6 1 2 7 0
0 2 3 4 1 5 6 9 7 8
0 2 3 4 1 5 6 9 7 8
0 1 2 4 3 5 6 9 7 8
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 9 7 8
0 1 2 3 4 5 6 8 7 9
0 1 2 3 4 5 6 7 8 9
*/ 
void Sort4fun(int data[],int left,int right){
    //当左已经大于或等于右,最多只有一个元素,不用排序了 
    if(left>=right)return;
    Show(data);
    //选择区域中第一个数作为枢轴 
    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);
}

//堆排序
//将数组视为完全二叉树,把他调整为一个堆,
//依次对换第一个元素和最后一个元素,并调整堆。 
/*
------堆排序--------
5 8 3 4 9 6 1 2 7 0
9 8 6 7 5 3 1 2 4 0
8 7 6 4 5 3 1 2 0 9
7 5 6 4 0 3 1 2 8 9
6 5 3 4 0 2 1 7 8 9
5 4 3 1 0 2 6 7 8 9
4 2 3 1 0 5 6 7 8 9
3 2 0 1 4 5 6 7 8 9
2 1 0 3 4 5 6 7 8 9
1 0 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
*/
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]){
        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;
    Show(data);
    //建堆 
    for(int i=size-1;i>=0;i--){
        Sort5fun(data,i,size);
    }
    
    //调整 
    for(int i=size-1;i>0;i--){
        Show(data);
        Swap(data[i],data[0]);
        Sort5fun(data,0,i);
    }
} 

//归并排序 
//把数组逐渐分解为小区间,对每两个个小区间使用
//合并有序数组算法,最终合并为一个 
/*
------归并排序------
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
5 8 3 4 9 6 1 2 7 0
3 5 8 4 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 6 1 2 7 0
3 4 5 8 9 1 2 6 7 0
0 1 2 3 4 5 6 7 8 9
*/ 
void Sort6fun(int data[],int left,int right,int temp[]){
    if(left>=right)return;
    Show(data); 
    
    //将数据分为两个组 
    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++;
    }
    
    //两路归并完成,数据复制到原数组中 
    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 
/*
------希尔排序------
5 8 3 4 9 6 1 2 7 0
5 1 2 4 0 6 8 3 7 9
0 1 2 3 5 4 7 6 8 9
0 1 2 3 4 5 6 7 8 9
*/
void Sort7(int data[],int size){
    cout<<"------希尔排序------"<<endl;
    for(int gap=size/2;gap>0;gap/=2){
        Show(data); 
        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]){
                    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;
} 
View Code

 

posted @ 2020-03-26 21:02  Wonder007  阅读(176)  评论(0)    收藏  举报