排序学习记录

#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b)
{
    return *(int*)a-*(int*)b;
}
void swap(int*a,int*b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}
//冒泡排序
void bubble_sort(int a[],int n)
{
    int i,j,flag;
    for(j=n-1;j>=0;j--)
    {
        flag=0;
        for(i=0;i<j;i++)
            if(a[i]>a[i+1])
            {
            	flag=1;
            	swap(&a[i],&a[i+1]);
			}
        if(flag==0)
		break; 
    }  
}
//插入排序
void insert_sort(int a[],int n)
{
    int i,j,temp;
    for(i=1;i<n;i++)
    {
        temp=a[i];
        for(j=i;j>0&&a[j-1]>temp;j--)
            a[j]=a[j-1];
        a[j]=temp;
    }
}
//希尔排序
void shell_sort(int a[],int n)
{
    int delta[]={929, 505, 209, 109, 41, 19, 5, 1, 0};//增量  也可以是2^n-1  互质就行
    int i,j,temp,s,D;
    for(s=0;delta[s]>=n;s++);  //将大于n的增量去掉
    for(D=delta[s];D>0;D=delta[++s])
    {
        for(i=D;i<n;i++)
        {
            temp=a[i];
            for(j=i;j>=D&&a[j-D]>temp;j-=D)
                a[j]=a[j-D];
            a[j]=temp;
        }
    }
}

//堆排序
void percdown(int a[],int p,int n)
{
    //实现以p为根节点的下滤
    int parent,child,temp;
    temp=a[p];
    for(parent=p;parent*2+1<n;parent=child)
    {
        child=parent*2+1;  //左孩子 因为没有标记 从1 开始 
        if(child!=n-1&&a[child]<a[child+1])
            child+=1;
        if(temp>=a[child]) break;   //不比孩子小,就在他父节点的位置
        else a[parent]=a[child];
    }
    a[parent]=temp;
}
void heapsort(int a[],int n)
{
    int i;
    for(i=n/2;i>=0;i--)
        percdown(a,i,n);//创建大顶堆
    for(i=n-1;i>0;i--)
    {
        swap(&a[0],&a[i]);
        percdown(a,0,i);
    }
}

//归并排序 递归方法
//实现两段区间的归并
void merge(int a[],int temp[],int l,int r,int rend)
{
    int lend,lenth,tmp,i;
    lend=r-1;
    tmp=l;
    lenth=rend-l+1;
    while(l<=lend&&r<=rend)
    {
        if(a[l]<=a[r])
            temp[tmp++]=a[l++];
        else
            temp[tmp++]=a[r++];
    }
    while(l<=lend)
        temp[tmp++]=a[l++];
    while(r<=rend)
        temp[tmp++]=a[r++];
    for(i=rend+1-lenth;i<=rend;i++)
    a[i]=temp[i];
    
}
void merge_sort(int a[],int temp[],int l,int rend)
{
    int center;
    if(l<rend)
    {
        center=(l+rend)/2;
        merge_sort(a,temp,l,center);
        merge_sort(a,temp,center+1,rend);
        merge(a,temp,l,center+1,rend);
    }
}
void mainmerge(int a[],int n)
{
    int temp[n];
    merge_sort(a,temp,0,n-1);

}


//归并排序  非递归
void merge_pass(int a[],int temp[],int n,int lenth)
{
    int i,j;
    for(i=0;i<=n-2*lenth;i+=2*lenth)
    {
        merge(a,temp,i,i+lenth,i+2*lenth-1);
    }
    if(i+lenth<n)
        merge(a,temp,i,i+lenth,n-1);
    else
        for(j=i;j<n;j++)
            temp[j]=a[j];
}
void nonrecur_merge(int a[],int n)
{
    int lenth=1;
    int *temp=(int*)malloc(sizeof(int)*n);
    while(lenth<n)
    {
        merge_pass(a,temp,n,lenth);
        lenth*=2;
        merge_pass(temp,a,n,lenth);
        lenth*=2;
    }
    free(temp);
}
  
//快速排序
//寻找三个的中位数,一种确定枢轴的方法 
int findmidloacat(int a[],int left,int right)
{
	int mid=(left+right)/2;
	if(a[left]>a[mid])
	swap(&a[left],&a[mid]);
	if(a[left]>a[right])
	swap(&a[left],&a[right]);
	if(a[mid]>a[right])
	swap(&a[mid],&a[right]);
	swap(&a[mid],&a[right-1]);
	//只需要从left+1到right-2与返回值比较了 
	return a[right-1];
}
void tempqsort(int a[],int left,int right)
{
	int flag,cutoff,low,high;
	cutoff=99;//定的一个阈值,如果长度较小则不用快速排序
	if(cutoff<right-left)
	{
		flag=findmidloacat(a,left,right);
		low=left;
		high=right-1;
		while(1)
		{
			while(a[++low]<flag);
			while(a[--high]>flag);
			if(low<high)
			swap(&a[low],&a[high]);
			else break;		
		}
		swap(&a[low],&a[right-1]);
		tempqsort(a,left,low-1);
		tempqsort(a,low+1,right);

	 } 
	else
	bubble_sort(a+left,right-left+1);
}
void Qsort(int a[],int n)
{
	tempqsort(a,0,n-1);
}
int main()
{
    
    int i,N;
    scanf("%d",&N);
    int a[N];
    for(i=0;i<N;i++)
        scanf("%d",&a[i]);
    
//    qsort(a,N,sizeof(int),cmp);
//     bubble_sort(a,N);
//     insert_sort(a,N);
//     shell_sort(a,N);
//     heapsort(a,N);
//     mainmerge(a,N);
//    nonrecur_merge(a,N);
	Qsort(a,N);
    for(i=0;i<N-1;i++)
        printf("%d ",a[i]);
    printf("%d",a[i]);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值