C++ 常用排序算法大全

/*
 * BubbleSort.cpp
 * 冒泡排序法,将一个数组由小到大排序。
 * 冒泡排序算法的基本思想是通过相邻两个记录之间的比较和交换,
 * 使关键码较小的记录逐渐从底部移向顶部(上升),
 * 关键码较大的记录逐渐从顶部移向底部(沉底).
 *  Created on: 2012-10-16
 *      Author: noure
 */
#include <iostream>
using namespace std;
#define N 10;  // 数组元素个数。
int main(){
    int A[N],i,j,t;
    for(i=0;i<N;i++){
        cin >> A[i];  // 输入N个数
    }
    for(j=0;j<N - 1;j++){
        for(i=0;i<N-1-j;i++){
            if(A[i] > A[i+1]){
                t = A[i];
                A[i] = A[i+1];
                A[i+1] = t;
            }
        }
    }
    for(i = 0;i<N;i++){
        cout << A[i] << " ";
    }
    return 0;
}

 

/*
 * InsertionSort.cpp
 * 插入排序法的基本思想是把新插入的关键码与已排好序的各记录关键码逐个比较,
 * 当找到第一个比新记录关键码大的记录时,该记录之前即为插入位置k.
 * 然后从序列最后一个记录开始到该记录,逐个后移一个单元,将新记录插入k位置.
 * 如果新记录关键码比序列中所有记录都大,则插入到最后位置.
 * 设由A[1]~A[n]的n个数据,插入排序的过程可以描述为:
 * 1,已经排序首先为A[1].
 * 2,然后将A[2]~A[n]逐个插入序列中,进行第i趟排序.将A[i]与A[1]~A[i-1]的关键码进行比较,
 * 若找到A[k]比A[i]大,则A[i-1]~A[k]逐个后移一个单元,将A[i]插入到k位置;
 * 若A[i]比所有元素都大,则什么也不做.重复进行n-1趟后,整个排序过程结束.
 *  Created on: 2012-10-16
 *      Author: noure
 */
#include <iostream>
#include <ctime>
using namespace std;
void InsertionSort(int A[],int n){
    int i,k,t;
    for(i = 1;i<n;i++){
        t=A[i],k=i-1;
        while(t < A[k]){
            A[k+1]=A[k],k--;
            if(k==-1) break;
        }
        A[k+1] = t;
    }
}

#define N 10;
int main(){
    int A[N],i;
    srand((unsigned int)time(0));
    for(i=0;i<N;i++){
        A[i] = rand()%100;
        cout<<A[i]<<" ";
    }
    cout<<endl;
    InsertionSort(A,N);
    for(i=0;i<N;i++) cout<<A[i]<<" ";
    return 0;
}

 

/*
 * QuickSort.cpp
 * 快速排序法的基本思想是:通过一趟排序将要排序的记录分隔成独立的两部分,
 * 其中一部分的所有记录关键码比另外一部分的记录关键码小,
 * 然后再按此方法对这两部分数据分别进行递归快速排序从而使序列成为有序序列.
 * 设有A[1]~A[n]的n个数据,选取第一个数据作为关键数据,然后将所有比它小的数据都放到它前面,
 * 所有比它大的数据都放到它后面,成为一趟排序.
 * 其算法是:
 * 1,设置两个变量,i,j.排序开始的时候,i等于左边界,j等于右边界.令关键数据s等于A[i];
 * 2,从i开始向后搜索,直到找到大于s的数.
 * 3,从j开始向前搜索,直到找到小于s的数.
 * 4,如果i<j,则交换A[i]和A[j].
 * 5,重复2~4步直到i>=j;将关键数据与A[j]交换
 *  Created on: 2012-10-18
 *      Author: noure
 */
#include <iostream>
#include <ctime>
using namespace std;

void QuickSort(int A[],int n,int left,int right){
    //快速排序,n为数组元素个数,left为数组左边界,right为数组右边界
    int i,j,t;
    if(left<right){
        i=left;
        j=right+1;
        while(1){
            while(i+1<n&&A[++i]<A[left]);//向后搜索,<升序,>降序
            while(j-i>-1&&A[--j]>A[left]);//向前搜索,>升序,<降序
            if(i>=j) break;
            t=A[i],A[i]=A[j],A[j]=t;
        }
        t=A[left],A[left]=A[j],A[j]=t;
        QuickSort(A,n,left,j-1);
        QuickSort(A,n,j+1,right);
    }
}

#define N 10;
int main(){
    int A[N],i;
    srand((unsigned int)time(0));
    for(i=0;i<N;i++){
        A[i] = rand()%100;
        cout<<A[i]<<" ";
    }
    cout<<endl;
    QuickSort(A,N,0,N-1);
    for(i=0;i<N;i++) cout<<A[i]<<" ";
    return 0;
}

 

/*
 * Search.cpp
 * 顺序查找法的基本思想是让关键字与序列中的数逐个比较,直到找出与给定关键字相同的数为止或序列结束.
 * 一般应用于无序序列查找.
 *  Created on: 2012-10-18
 *      Author: noure
 */
#include <iostream>
using namespace std;
int Search(int A[],int n,int find){
    int i;
    for(i=0;i<n;i++)
        if(A[i] == find)
            return i;
    return -1;
}
#define N 10;
int main(){
    int A[N]={18,-3,-12,34,101,211,12,90,77,45},i,find;
    cin>>find;
    i=Search(A,N,find);
    if(i>=0) cout<<"A["<<i<<"]="find<<endl;
    else cout<<"not found"<<endl;
    return 0;
}
/*
 * SelectionSort.cpp
 * 选择排序算法
 * 选择排序法的基本思想是第i躺选择排序通过n-i次关键码的比较,
 * 从n-i+1个记录中选出关键码最小的记录,并和第i个记录进行交换.
 * 设由A[1]~A[n]的n个数据,选择排序的过程可以描述为:
 * 1,首先在A[1]~A[n]区间内进行比较,从n个记录中选出最小的记录A[k],
 * 若k不为1则将A[1]和A[k]交换,A[1]为具有最小关键码的元素,称第一趟排序结束.
 * 2,然后在A[i]~A[n]区间内,进行第i趟排序,从n-i+1个记录中选出最小的记录A[k],
 * 若k不为i则将A[i]和A[k]交换.重复进行n-1趟后,整个排序过程结束.
 *  Created on: 2012-10-16
 *      Author: noure
 */

#include <iostream>
#include <ctime>
using namespace std;
void SelectionSort(int A[],int n){
    int i,j,k,t;
    for(i = 0;i<n-1;i++){  // 选择排序法
        k = i;
        for(j = i+1;j<n;j++){   // 一趟选择排序
            if(A[j] <a[k]) k = j;  // 升序/降序
            if(i!=k) t=A[i],A[i] = A[k] ,A[k] =t;
        }
    }
}

#define N 10;
int main(){
    int A[N],i;
    srand(unsigned int)time(0);
    for(int i=0;i<N;i++){
        A[i] = rand()%100;
        cout << A[i] <<" ";
    }
    cout << endl;
    SelectionSort(A,N);
    for(i=0;i<N;i++) cout << A[i] << " ";
    return 0;
}
/*
 * BinarySearch.cpp
 * 二分查找法,对于有序序列,可以采用二分查找法查找.
 * 其基本思想是:将升序排列的n个元素的集合A分成元素个数大致相同的两部分,取A[n/2]与欲查找的find作比较.
 * 若果相等则表示找到find,算法终止.
 * 如果find<A[n/2],则在A的前半部分继续搜索find,如果find>A[n/2],则在A的后半部继续搜索find.
 *  Created on: 2012-10-18
 *      Author: noure
 */

#include <iostream>
using namespace std;
int BinarySearch(int A[],int n,int find){
    int low,upper,mid;
    low=0,upper=n-1;
    while(low<=upper){
        mid = low+(upper-low)/2;
        if(A[mid]<find){
            low = mid+1;
        }else if(A[mid] >find){
            upper=mid-1;
        }else{
            return mid;
        }
    }
    return -1;
}
#define N 10;
int main(){
    int A[N] = {8,24,30,47,62},i,find;
    cin>>find;
    i = BinarySearch(A,N,find);
    if(i >=0) cout << "A[" << i <<"]=" << find<<endl;
    else cout<<"not found "<<endl;
    return 0;
}
/*
 * CoderBlod1.cpp
 * 空间换时间.
 * 算法的执行总是需要计算机的时间和空间.由于现在计算机的内存趋向于大容量.
 * 所以空间复杂性相对于时间复杂性来说不那么重要.就出现了以消耗空间来换取时间的编程方法.
 * eg:一个只能被素数2,3,5,7整除的数成为Humble Number(简称丑数),
 * 数列{1,2,3,4,5,6,7,8,9,10,12,14,15,16,18,……}是前15个丑数(把1也算作丑数).
 * 编程输入n(1<=n<=5842),输出这个数列的第n项.
 * 分析:
 * 显然,可以用枚举法来求解,枚举一个自然数H,逐一检查H是否只能被2,3,5,7整除,
 * 方法是去掉H所有的2,3,5,7因子,如果结果为1,则H是丑数;
 * 例如16/2/2/2/2=1,18/2/3/3=1,结果为1,所以16和18是丑数,
 * 而22/2=11,结果不为1,所以22不是丑数,以此类推.
 *  Created on: 2012-10-18
 *      Author: noure
 */
#include <iostream>
using namespace std;
int main(){
    int cnt=0,n,H=0,t;
    cin>>n;
    while(cnt < n){  //数列第n项时结束
        H++,t=H;    //下一个自然数
        while(t%2 == 0) t = t/2;    //去除所有因子2
        while(t%3 == 0) t = t/3;    //去除所有因子3
        while(t%5 == 0) t = t/5;    //去除所有因子5
        while(t%7 == 0) t = t/7;    //去除所有因子7
        if(t == 1) cnt++;
    }
    cout << H << endl;
    return 0;
}
/*
 * CoderBlod2.cpp
 * 空间换时间.
 * 算法的执行总是需要计算机的时间和空间.由于现在计算机的内存趋向于大容量.
 * 所以空间复杂性相对于时间复杂性来说不那么重要.就出现了以消耗空间来换取时间的编程方法.
 * eg:一个只能被素数2,3,5,7整除的数成为Humble Number(简称丑数),
 * 数列{1,2,3,4,5,6,7,8,9,10,12,14,15,16,18,……}是前15个丑数(把1也算作丑数).
 * 编程输入n(1<=n<=5842),输出这个数列的第n项.
 * CoderBlod1.cpp可以将结果求解出来,但是当n是5842时,程序运行时间会很长,
 * 因为5842时H已经枚举到20亿.
 * 换一种思路求解:
 * 根据丑数的定义,一个数与{2,3,5,7}的积一定也是丑数.
 * 例如:{1*2,1*3,1*5,1*7},{2*2,2*3,2*5,2*7}……均为丑数.由于丑数是自然数顺序且是唯一的.
 * 需要对乘积进行优选,例如2*3和3*2的结果都是6,需要排除一个.
 * 3*2的结果大于1*5,所有应该先选1*5.因此假设一个集合A用来存储丑数.
 * 最开始的元素为{1},按下面的方法将得到的最小丑数插入到A中作为新的丑数:
 * A(n) = main(A(i)*2,A(j)*3,A(k)*5,A(m)*7)
 * n>i,j,m,且i,j,k,m只有在本项被选中才向后移动.
 * 例如:
 * 开始时A为{1}i=1,j=1,k=1,m=1
 * min(1*2,1*3,1*5,1*7)为2,插入到A为(1,2},i=2,j=1,k=1,m=1
 * min(2*2,1*3,1*5,1*7)为3,插入到A为(1,2,3},i=2,j=2,k=1,m=1
 * min(2*2,2*3,1*5,1*7)为4,插入到A为(1,2,3,4},i=3,j=2,k=1,m=1
 * min(3*2,2*3,1*5,1*7)为5,插入到A为(1,2,3,4,5},i=3,j=2,k=2,m=1
 * min(3*2,2*3,2*5,1*7)为6,插入到A为(1,2,3,4,5,6},i=4,j=2,k=2,m=1
 * min(4*2,3*3,2*5,1*7)为7,插入到A为(1,2,3,4,5,6,7},i=4,j=2,k=2,m=2
 * 以此类推
 *  Created on: 2012-10-18
 *      Author: noure
 */
#include <iostream>
using namespace std;
int min(int a,int b,int c,int d){ //求4个数的最小值
    a=a>b?b:a;
    c=c>d?d:c;
    return a>c?c:a;
}
int main(){
    int i=1,j=1,k=1,m=1,n=1;
    int A[6000]={1,1};  //数列第一项
    for(n=2;n<5848;n++){
        int t1,t2,t3,t4;    //计算2,3,5,7的乘积
        t1=A[i]*2,t2=A[j]*3,t3=A[k]*5,t4=A[m]*7;
        A[n]=min(t1,t2,t3,t4);    //取最小值
        if(A[n] == t1) i++;        //移动i
        if(A[n] == t2) j++;        //移动j
        if(A[n] == t3) k++;        //移动k
        if(A[n] == t4) m++;        //移动m
    }
    cin >>  n;
    cout << A[n] << endl;    //输出第n项的丑数.
    return 0;
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值