排序算法实现

一、排序算法分类



二、算法实现

归并算法思想:

void mergesort(int a[],int b[],int left, int right)

{

if(left>=right)

return ;

int mid=(left+right)/2;

mergesort(a,b,left,mid);

mergesort(a,b,mid+1,right);


merge(a,b,left,mid,right);//合并到数组b中

copy(a,b,left,right)//复制回数组a中

}


#include <stdio.h>
#define leftchild(i) (2*(i)+1)  //用于堆排序
int a[9]={9,8,7,6,5,4,3,2,1};
int b[9]={0};
//排序
//插入排序
//1)直接插入排序
//直接插入排序由N-1趟排序组成。对于P=1趟到P=N-1趟,插入排序保证了位置0~P上的元素为已排序状态。
//插入排序利用这样的事实:位置0~位置P-1上的元素是已排序过的。

void insert_sort(int v[],int n)
{
	int i;
	int j;
	int temp;
	for(i=1;i<n;i++)
	{
		temp=v[i];
		for(j=i-1;j>=0&&v[j]>temp;j--)
			v[j+1]=v[j];

		v[j+1]=temp;
	}
}
//插入排序
//1)shell排序
//希尔排序又叫缩小增量排序,个趟比较所用的距离随算法的进行而减小,直到之比较相邻元素的最后一趟为止。
//
void shell_sort(int v[],int n)
{
	int i,j,increment;
	int temp;

	for(increment=n/2;increment>0;increment /=2)
	{
		for(i=increment;i<n;i++)
		{
			temp=v[i];
			for(j=i;j>=increment&&v[j-increment]>temp;j-=increment)
				v[j]=v[j-increment];

			v[j]=temp;
		}
	}
}

//交换排序
//1)冒泡排序
//算法要进行P趟(P最大为N-1)排序,每趟排序将把v[0]~v[P]中最大的元素送到(通过相邻二个元素的交换)v[P]的位置
//如果某趟排序没有进行元素交换,则break;该排序已经完成。

void bubble_sort(int v[],int n)
{
	int i,j;
	int temp;
	int flag;
	for(i=n-1;i>=0;i--)
	{
		flag=0;
		for(j=0;j<i;j++)
		{
			if(v[j]>v[j+1])
			{
				temp=v[j+1];
				v[j+1]=v[j];
				v[j]=temp;
				flag=1;
			}
		}
		if(flag==0)
			break;
	}
}

//交换排序
//2)快速排序
//快速排序是是一种分治的递归算法。所谓分治算法就是分(递归解决较小的问题)与治(然后,从子问题的解 构建原问题的解)。
//思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小(两个不相交集),
//然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
void swap(int *x,int *y)
{
	int temp;
	temp=*y;
	*y=*x;
	*x=temp;
}
void  qicsort(int v[],int l,int r)
{
	int temp;
	int left=l;
	int right=r;
	int mid=(left+right)/2;
	if(left>=right)
		return ;

	swap(&v[left],&v[mid]);
	temp=v[left];

	while(left<right)
	{
		while(v[right]>temp&&left<right)
			right--;
		
		v[left]=v[right];

		while(v[left]<temp&&left<right)
			left++;

		v[right]=v[left];
	}
	if(left==right)
	v[left]=temp;

	qicsort(v,l,left-1);

	qicsort(v,left+1,r);
	/*如果上面两行代买写成qicsort(v,l,mid-1);qicsort(v,mid+1,r)??
	*/
}

//选择排序
//1)简单选择排序
//每一趟从待排序的数据元素中选出最小或最大的一个,顺序放在已排序好数列的最后,知道全部有待排序的数据元素排序完。
void select_sort(int v[],int n)
{
	int i,j;
	int min;
	int temp;
	for(i=0;i<n;i++)
	{
		min=i;
		for(j=i+1;j<n;j++)
		{
			if(v[j]<v[min])
				min=j;
		}

		temp=v[min];
		v[min]=v[i];
		v[i]=temp;
	}

}
//选择排序
//2)堆排序
//堆排序第一步已线性的时间建立一个堆(大头堆),然后通过将堆中的最后元素与第一个元素交换,缩减堆的大小并进行shift,来执行N-1次将末尾元素与堆顶元素的交换。///当算法终止时,数组则以所排的顺序包含这些元素。
void shift(int v[],int i,int n)
{
	int child;
	int temp;

	for(temp=v[i];leftchild(i)<n;i=child)
	{
		child=leftchild(i);
		if(child!=n-1&&v[child+1]>v[child])
			child++;

		if(v[child]>temp)
			v[i]=v[child];
		else
			break;

	}
		v[i]=temp;
}
void heap_sort(int v[],int n)
{
	int i,j;
	for(i=n/2;i>=0;i--)
		shift(v,i,n);
	for(j=n-1;j>0;j--)
	{
		swap(&v[0],&v[j]);
		shift(v,0,j);
	}
}
//归并排序
//归并排序是将两个有序表合并成一个新的有序表,即把待排序序列分为若干个有序的子序列,再把有序的子序列合并为整体有序序列。
//归并排序也是一种分治思想的算法。
void merge(int v[],int w[],int left,int mid,int right)
{
	int i,num;
	int flag,flag1,flag2;
	flag1=left;
	flag2=mid+1;
	flag=flag1;
	num=right-left+1;
	while(flag1<=mid&&flag2<=right)
	{
		if(v[flag1]<=v[flag2])
		{
			w[flag++]=v[flag1++];

		}
		else
		{
			w[flag++]=v[flag2++];
		}
	}

	while(flag1<=mid)
		w[flag++]=v[flag1++];

	while(flag2<=right)
		w[flag++]=v[flag2++];

	for(i=0;i<num;i++,right--)
		a[right]=b[right];
}

void merge_sort(int v[],int w[],int left,int right)
{
	int mid;
	if(left<right)
	{
		mid=(left+right)/2;
		merge_sort(v,w,left,mid);
		merge_sort(v,w,mid+1,right);
		merge(v,w,left,mid,right);
	}

}
void init(int v[],int n)
{
	int i;
	for(i=0;i<n;i++)
		v[i]=n-i;
}

void print(int v[],int n)
{
	int i;
	for(i=0;i<n;i++)
		printf("%d%c",v[i],i==n-1?'\n':' ');
}

main()
{
	printf("初始序列为:\n-----------------------\n");
	print(a,9);
	printf("直接插入排序:\n----------------------\n");
	init(a,9);
	insert_sort(a,9);
	print(a,9);
	printf("shell排序:\n----------------------\n");
	init(a,9);
	shell_sort(a,9);
	print(a,9);
	printf("冒泡排序:\n----------------------\n");
	init(a,9);
	bubble_sort(a,9);
	print(a,9);
	printf("快速排序:\n----------------------\n");
	init(a,9);
	qicsort(a,0,8);
	print(a,9);
	printf("直接选择排序:\n----------------------\n");
	init(a,9);
	select_sort(a,9);
	print(a,9);
	printf("堆排序:\n----------------------\n");
	init(a,9);
	heap_sort(a,9);
	print(a,9);
	printf("归并排序:\n----------------------\n");
	init(a,9);
	merge_sort(a,b,0,8);
	print(a,9);
	return 0;
}



注:

在快速排序代码中如果注释两行代码

//if(left>=right)
  //return ;

会出现错误:



这实际上是数组越界了...


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值