排序算法汇总 c++

#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <iostream>

using namespace std;

template<typename T> void v_print( vector<T>& v){
    int v1(v.size());
    for(int k1(0);k1<v1;++k1)
        cout<<v[k1]<<" ";
    cout<<endl;
}


/*冒泡排序:依次比较相邻的数据,小数据放前,大数据放后。
第一趟将最大数滚到最后一个位置,第二趟将次大的数滚到倒数第二个位置,...,依次将“最大数”的滚动到“最后”,共需要n-1趟。
时间复杂度O(n^2),空间复杂度为O(1)。
稳定排序,元素较少时效率较高。*/
template<typename T> void bubbleSort1( vector<T>& v){
    int v1(v.size());
    for(int k1(0);k1<v1-1;++k1){
        for(int k2(0);k2<v1-1-k1;++k2){
            if(v[k2+1]<v[k2])swap(v[k2+1],v[k2]);
            //v_print(v);
        }
    }
}
/*冒泡排序优化:设置一个标志,如果第一次比较完没有交换,即说明已经有序,不应该进行下一次遍历,还有已经遍历出部分有序的序列后,
那部分也不用进行遍历。
最坏情况,反序序列,时间复杂度O(n^2);最好情况,正序,时间复杂度O(n)。*/
template<typename T> void bubbleSort2( vector<T>& v ){
    int v1(v.size());
    bool flag(1);
    //cout<<v1<<endl;
    for(int k1(0);k1<v1-1&&flag;++k1){
        flag=false;
        for(int k2(0);k2<v1-1-k1;++k2){
            if(v[k2+1]<v[k2])swap(v[k2+1],v[k2]),flag=true;
            //v_print(v);
        }
    }
}
/*选择排序:正序,第一趟遍历N个数据,找到最小的数值与第一个元素交换,第二趟遍历剩下N-1个元素,找出其中最小的数值与第二元素交换...
与冒泡的查找过程一样,但是选择排序每一趟只最后交换一次,因此选择排序的效率相较于冒泡只高不低。
时间复杂度O(n^2),空间复杂度为O(1)。*/
template<typename T> void selectSort( vector<T>& v){
    int v1(v.size());
    for(int k1(0),km(0);k1<v1-1;++k1,km=k1){
        for(int k2(k1+1);k2<v1;++k2){
            if(v[k2]<v[km])km=k2;
        }
        swap(v[km],v[k1]);
        //v_print(v);
    }
}
/*插入排序:与扑克摸牌一样。插入即表示将一个新数据插入到一个有序数组中,并保持有序。
时间复杂度:最好的情况O(n);最坏的情况O(n^2)。空间复杂度O(1)。
稳定排序,元素少是效率好。*/
template<typename T> void insertSort( vector<T>& v){
    int v1(v.size());
    for(int k1(1),k2,tem;k1<v1;++k1){
        for(tem=v[k1],k2=k1;0<k2 && tem<v[k2-1];--k2){
            v[k2] = v[k2-1];
            //v_print(v);
        }
        v[k2] = tem;
        //v_print(v);
    }
}

/*希尔排序:按照不同步长对元素进行插入排序,步长逐步递减直到为1。又称为缩小增量排序。
时间复杂度依赖于增量序列,平均O(nlogn),最差O(n^2)
不稳定排序,空间复杂度O(1)。*/
template<typename T> void shellSort( vector<T>& v){
    int v1(v.size());
    for(int kd(v1/2);kd;kd>>=1){
        for(int k1(0);k1<kd;++k1){
            for(int k2(k1+kd);k2<v1;k2+=kd){
                for(int k3(k2);k1<k3;k3-=kd){
                    if(v[k3]<v[k3-kd])
                        swap(v[k3],v[k3-kd]);
                    /*else
                        v_print(v);*/
                }
            }
        }
    }
}

template<typename T> void shellSort1( vector<T>& v){
    int t=0;
    int v1(v.size());
    T tem;
    for(int kd=(v1/2);kd>0;kd>>=1){
        for(int k1(kd),k2;k1<v1;k1+=kd){
            for(k2=k1,tem=v[k1];k2>0&&tem<v[k2-kd];k2-=kd){
                v[k2]=v[k2-kd];
                //v_print(v);
            }
            v[k2]=tem;
            //v_print(v);t++;
        }
    }
    cout<<"t="<<t<<endl;
}

/*归并排序:先递归地将序列分为短序列,递归出口为短序列只有一个元素,然后把各个有序的短序列合并为一个有序序列。
时间复杂度:O(nlogn),稳定,适合元素较多的情况。*/
template<typename T> void mergearray(vector<T>& a,int first,int mid,int last,vector<T>& temp)
{
    int i=first,j=mid+1;
    int n=mid,m=last;
    int k=0;

    while( i<=n && j<=m )
    {
        if(a[i]<a[j])
            temp[k++]=a[i++];
        else
            temp[k++]=a[j++];
    }

    while(i<=n)
        temp[k++]=a[i++];
    while(j<=m)
        temp[k++]=a[j++];

    for(i=0;i<k;i++)
        a[first+i] = temp[i];
}
template<typename T> void merge(vector<T>& a,int first,int last,vector<T>& temp){
    if(first<last)
    {
        int mid = (first+last)/2;
        merge(a,first,mid,temp);
        merge(a,mid+1,last,temp);
        mergearray(a,first,mid,last,temp);
    }
}

template<typename T> void mergeSort( vector<T>& v){
    int v1(v.size());
    vector<T> p(v1);
    merge(v,0,v1-1,p);
}
/*快速排序:划分交换排序,采用分治策略。先从数列末尾取一个元素作为基准元;然后将小于它的元素放在左边,不小于的放在右边;然后再对左右区间重复第二步,直至只要一个元素。
时间复杂度的最好情况和平均情况一样为O(nlogn),最坏情况下为O(n^2 )。空间复杂度为O(1)。
不稳定排序。*/
template<typename T> int partition( vector<T>& v,int first,int last ){
    int kt(first);
    for(int k1(first);k1<last;++k1){
        if(v[k1]<v[last]){
            swap(v[kt++],v[k1]);
            //v_print(v);
        }
    }
    swap(v[kt],v[last]);
    //v_print(v);
    return kt;
}

template<typename T> void quickSort( vector<T>& v,int first,int last){
    if(first<last)
    {
        int pivot = partition(v,first,last);
        quickSort(v,first,pivot-1);
        quickSort(v,pivot+1,last);
        //v_print(v);
    }
}

template<typename T> void quickSort( vector<T>& v ){quickSort(v,0,v.size()-1);}

/*堆排序:初始化堆;将当前无序去的堆顶元素通该区域最后一个元素交换,然后调整堆,即将堆顶元素“下沉”到正确的位置。
时间复杂度:最好,最坏都是O(nlogn),较多元素的时候效率比较高,空间复杂度为O(1)。
不稳定排序。*/
template<typename T> void minheapfixdown( vector<T>& v,int i, int n){
    T temp=v[i];
    int j=2*i+1;

    while(j<n)
    {
        if( j+1<n && v[j+1]<v[j] )
            j++;
        if(v[j] >= temp)
            break;

        v[i]=v[j];
        i=j;
        j=i*2+1;

    }
    v[i] = temp;
}

template<typename T> void maxheapfixdown( vector<T>& v,int i, int n){
    T temp=v[i];
    int j=2*i+1;

    while(j<n)
    {
        if( j+1<n && v[j+1]>v[j] )
            j++;
        if(v[j] <= temp)
            break;

        v[i]=v[j];
        i=j;
        j=i*2+1;

    }
    v[i] = temp;
}

template<typename T> void buildheap( vector<T>& v,int v1){
    for(int k1(v1/2-1);k1>=0;k1--)maxheapfixdown(v,k1,v1);
}

template<typename T> void heapSort( vector<T>& v ){
    int v1(v.size());
    buildheap(v,v1);
    for(int k1(v1-1);k1>0;--k1){
        swap(v[k1],v[0]);
        maxheapfixdown(v,0,k1);
    }
}

void main()
{
    int num[]={2,5,6,8,4,3,9,1,0,7};

    vector<int> v(num,num+10);//vs2010没办法不支持C++11/(ㄒoㄒ)/

    string str[]={"a","is","the","first","word"};

    vector<string> s(str,str+5);

    cout<<"before:"<<endl;
    v_print(v);

    //bubbleSort1(v);

    bubbleSort2(v);

    //insertSort(v);

    //selectSort(v);

    //shellSort(v);
    //shellSort1(v);

    //mergeSort(v);

    //quickSort(v);

    //heapSort(v);

    cout<<"after:"<<endl;
    v_print(v);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值