插入排序,合并排序,堆排序,快速排序,计数排序的实现(算法导论)

插入排序

#include <iostream>
#define MAX_SIZE 1000
using namespace std;

//插入排序,pa为指向数组的指针,n为数组元素个数
void insert_sort(int *pa,int n)
{
    int i,key,j;
    for(j=1;j<n;j++)
    {
        i=j;
        key=*(pa+i);
        while(i>0&&key<*(pa+i-1))
        {
            *(pa+i)=*(pa+i-1);
            i--;
        }
        *(pa+i)=key;
    }
   
}
int main()
{
    int A[MAX_SIZE],i;
    for(i=0;i<10;i++)
        A[i]=10-i;
    int *p=A;
    insert_sort(p,10);
    for(i=0;i<10;i++)
        cout<<A[i]<<endl;
    return 1;
}

合并排序

#include <iostream>
using namespace std;
//定义数组中的最大值
#define MAX_NUM 1000
//定义数组元素个数
#define MAX_SIZE 1000
//pa是指向A数组的指针,p,q,r为数组下标
//假设A[p..q],A[q+1..r]已经排好序,返回A[p..r]已经排好序的A
//思路是将A[p..q],A[q+1..r]分别赋值给数组A1,A2,并将最后一个元素设为最大值,作为哨兵
//然后用两个指针i,j从小到大赋值到A
void merge(int *pa,int p,int q,int r)
{
    int n1,n2,i,j,k;
    n1=q-p+1;
    n2=r-q;
   
    //p1,p2分别为指向A1,A2的指针
    int *p1,*p2;
    p1=new int[n1+1];
    p2=new int[n2+1];
    //将A[p..q],A[q+1..r]分别赋值给数组A1,A2
    for(i=0;i<n1;i++)
        *(p1+i)=*(pa+p+i);
    for(i=0;i<r-q;i++)
        *(p2+i)=*(pa+q+i+1);
    //将最后一个元素设为最大值,作为哨兵
    *(p1+n1)=MAX_NUM;
    *(p2+n2)=MAX_NUM;

    //用指针i,j从小到大赋值到A
    i=0;j=0;
    for(k=p;k<=r;k++)
    {
        if(*(p1+i)>=*(p2+j))
        {
            *(pa+k)=*(p2+j);
            j++;
        }
        else
        {
            *(pa+k)=*(p1+i);
            i++;
        }
    }
    free(p1);
    free(p2);
}
//合并排序,pa为指向数组A的指针,p,r为下标,对A[p..r]进行合并排序
void merge_sort(int *pa,int p,int r)
{
    if(p<r)
    {
        int q=(p+r)/2;
        merge_sort(pa,p,q);
        merge_sort(pa,q+1,r);
        merge(pa,p,q,r);
    }
}

int main()
{
    int A[MAX_SIZE],i;
    for(i=0;i<10;i++)
        A[i]=10-i;
    int *pa=A;
    merge_sort(pa,0,9);
    for(i=0;i<10;i++)
        cout<<A[i]<<endl;
    return 1;
}

 

堆排序

#include <iostream>
using namespace std;
#define MAX_SIZE 1000
int heap_size;

//返回父节点序号:i/2
int parent(int i)
{
    return i>>1;
}
//返回左孩子节点序号:2i
int left(int i)
{
    return i<<1;
}
//返回右孩子节点序号:2i+1
int right(int i)
{
    return left(i)+1;
}

//交换指针p1,p2指向的值
void exchange(int *p1,int *p2)
{
    int temp=*p1;
    *p1=*p2;
    *p2=temp;
}

//保持最大堆的性质,pa为指向A[]的数组,i为下标
//假设left(i),right(j)满足最大堆的性质,但A[i]可能小于其左右子树
//该过程保持其最大堆的性质,使A为最大堆
void max_heapify(int *pa,int i)
{
    int l,r,largest;
    l=left(i);
    r=right(i);
    if(l<=heap_size&&*(pa+l)>*(pa+i))
        largest=l;
    else
        largest=i;
    if(r<=heap_size&&*(pa+r)>*(pa+largest))
        largest=r;
    if(largest!=i)
    {
        exchange((pa+i),(pa+largest));
        max_heapify(pa,largest);
    }
}

//建堆,pa为指向A[]的数组,n为数组大小
void build_max_heap(int *pa,int n)
{
    int i;
    heap_size=n;
    for(i=n/2;i>0;i--)
    {
        max_heapify(pa,i);//对每个非叶子节点调用一次max_heapify()
    }
}

//堆排序,pa为指向A[]的数组,n为数组大小
//注意:要排序的元素下标从1开始
void heap_sort(int *pa,int n)
{
    int i;
    //建堆
    build_max_heap(pa,n);
    for(i=n;i>1;i--)
    {
        exchange(pa+1,pa+heap_size);
        heap_size--;
        max_heapify(pa,1);
    }
}

int main()
{
    int A[MAX_SIZE],i;
    for(i=1;i<=10;i++)
        A[i]=i;
    int *pa=A;
    //堆排序
    heap_sort(pa,10);
    for(i=1;i<=10;i++)
        cout<<A[i]<<endl;
    return 1;
}

 

快速排序

#define MAX_SIZE 100
#include <iostream>
using namespace std;

//交换指针p1,p2指向的值
void exchange(int *p1,int *p2)
{
    int temp=*p1;
    *p1=*p2;
    *p2=temp;
}
//pa为指向A[]的数组,p,r为下标,对A[p..r]进行就地重排,以A[r]为主元
//划分为小于主元和大于主元的两部分,返回主元的下标q
//例如:A[1..6]={18,8,16,6,9,10}结果:A[1..6]={8,6,9,10,18,16} q=4
//(元素顺序可能与结果不一致,但小于10的元素在10前面,大于10的元素在10后面)
int partition(int *pa,int p,int r)
{
    int x=*(pa+r); //主元
    int i=p-1,j;  //i表示小于主元的最后一个元素
    for(j=p;j<r;j++)
    {
        if(*(pa+j)<x)
        {
            i++;
            exchange((pa+i),(pa+j));
        }
    }
    exchange((pa+r),(pa+i+1));
    return i+1;
}
//快速排序
void quick_sort(int *pa,int p,int r)
{
    if(p<r)
    {
        int q=partition(pa,p,r);
        quick_sort(pa,p,q-1);
        quick_sort(pa,q+1,r);
    }
}

int main()
{
    int A[MAX_SIZE],i;
    for(i=1;i<=10;i++)
        A[i]=11-i;
    int *pa=A;
    //快速排序
    quick_sort(pa,1,10);
    for(i=1;i<=10;i++)
        cout<<A[i]<<endl;
    return 1;
}

 

计数排序 

#include <memory>
#include <iostream>
using namespace std;
#define MAX_SIZE 1000  //数组大小
#define MAX_NUM 1000    //数组中最大值
int main()
{   
    int A[MAX_SIZE],i,n=10;
    for(i=1;i<=n;i++)
        A[i]=n-i+1;

    //计数排序,A[]为初始数组,下标从1开始,B[]为结果数组,下标从1开始,C[]为辅助数组
    int C[MAX_NUM],max_element=0;
    int B[MAX_SIZE],temp;
    memset(C,0,4*MAX_NUM);
    for(i=1;i<=n;i++)
    {
        temp=A[i];
        if(temp>max_element)
            max_element=temp;
        C[temp]++;
    }
    for(i=0;i<=max_element;i++)
        C[i+1]+=C[i];

    for(i=n;i>=1;i--)
    {
        B[C[A[i]]]=A[i];
        C[A[i]]--;
    }


    for(i=1;i<=n;i++)
        cout<<B[i]<<endl;
    return 1;
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值