排序算法总结

直接插入排序

/*总是将a[i]与a[i+1]作比较,temp记录两者中较小的数
然后对这个数左边遍历将比temp大的数右移, 
然后在空出来的位置上插入temp进行排序*/
#include <stdio.h>
insert_sort(int a[],int n)
{
	int i,j,temp;
	for(i=1;i<n;i++)
	{
		if(a[i] <a[i-1])
		{
			temp=a[i];
			for(j=i-1; a[j]>temp; j--)
			{
				a[j+1]=a[j];//从下标j处,所有的元素都右移 
			}
			a[j+1]=temp;
		}
	}
}
int main(void)
{
	int i,a[10]={0,1,3,2,9,6,5,8,7,4};
	insert_sort(a, 10);
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
}

选择排序

/*用index记录数组的未排序部分的第一个位置i=index,
从它的下一位置开始遍历所有元素与该位置处的数比较,找到最小的并用index记录该处下标
将a[i]与a[index]作值交换,如此往复。
与冒泡算法相比,比较次数无变化,但值交换的次数减少*/

#include <stdio.h>
void select_sort(int a[],int n)
{
	int i,j,index,temp;
	int count1=0,count2=0; 
	for(i=0;i<n-1;i++)
	{
		index=i;
		for(j=i+1;j<n;j++){
			count1++; 
			if(a[j] <a[index])	{index=j;count2++;} 
		}		
		temp=a[index];
		a[index]=a[i];
		a[i]=temp;		
	}
	printf("共进行%d次比较%d次值交换\n",count1,count2);
}

int main(void)
{
	int i,a[10]={0,1,3,2,4,6,5,7,8,9};
	select_sort(a, 10);
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
} 

希尔排序

/*希尔排序基本思想:先将整个记录序列分割成若干个子序列分别进行直接插入排序,
待整个序列中的记录基本有序时,再对全体记录进行一次直接插入排序
其实就是对插入排序的改进a[i-gap]与a[i]比较,时间复杂度与gap的值有关系。应使gap值为 
没有除1之外的公因子,并且最后gap值必须为1*/ 
#include <stdio.h>
void shell_sort(int a[],int n)
{
	int i,j,temp;
	int gap=n; 
	do
	{
		gap=gap/3+1;
		for(i=gap;i<n;i++)
		{
			if(a[i] <a[i-gap])
			{
				temp=a[i];
				for(j=i-gap; a[j]>temp; j-=gap)
				{
					a[j+gap]=a[j];//从下标j处,所有的元素都右移 
				}
			a[j+gap]=temp;
			}
		}
		
	}while(gap>1);
	
}

int main(void)
{
	int i,a[10]={0,9,2,3,4,6,7,1,5,8};
	shell_sort(a, 10);
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
}

冒泡排序

/*数组中左右相邻的元素a[i-1]与a[i]相互之间进行比较,若a[i-1]<a[i]则交换数值
最终可以使得大的数不断往后移动实现排序功能*/

#include <stdio.h>
void bubble_sort(int k[],int n)
{
	int i,j,temp,flag=1;
	int count1=0,count2=0;
	for(i=0; i<n-1 && flag; i++)
	{
		for(j=n-1; j>i; j--)//加入flag标志,减少比较次数 
		{
			count1++;
			flag=0;
			if(k[j-1] > k[j])
			{
				temp=k[j-1];
				k[j-1]=k[j];
				k[j]=temp;
				flag=1;
				count2++;
			}
		}
	}
	printf("共进行了%d次比较%d次值交换",count1,count2);
}

int main(void)
{
	int i,a[10]={0,1,3,2,4,6,5,7,8,9};
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
	bubble_sort(a, 10);
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
}

快速排序

/*快速排序是对冒泡排序的一种改进,它的基本思想就是通过一趟排序将
待排序记录分割成独立的两个部分,其中一部分记录的关键字比另一部分
记录的关键字小,则可分别对这两部分记录继续进行排序,已达到整个序列有序
快速排序是目前被认为是最好的一种内部排序算法*/

#include <stdio.h>
void QuickSort(int a[], int n)//n为数组的长度 
{
	int low=0,high=n-1;
	int temp,temq;
	int pivot=a[low];//枢轴值 
	if(n >1 )
	{
	while(low <high)
	{
		while(low<high && a[high] >= pivot )
			--high;
		a[low]= a[high];//比pivot小的都放在左边 
		while(low<high && a[low] <=pivot)
			++low;		
		a[high]=a[low];//比pivot大的都放到右边 
	}
	a[low]=pivot;//此时low=high 
	QuickSort(a,low);//对low的左边部分进行排序 
	QuickSort(a+low+1, n-low-1);/*对i+2到numsize这numsize-1-i个数排序*/
	}
	
} 

int main(void)
{
	int a[8];
	int i;
	for(i=0;i<8;i++)
		scanf("%d", a+i);
		
	QuickSort(a,8);
	for(i=0;i<8;i++)
		printf("%d",a[i]);
}


归并排序

/*将含有n个记录的序列看作n个有序的子序列,每个子序列的长度为1,然后两两归并,
得到n/2个长度为2的子序列,如此往复最终求解
将长度n的序列向下递归分解为左右两部分,知道L/R长度为1,
然后向上倒退合并,并将排序后的值保存在Llist数组中,因为它的首地址就是数组A的地址*/

#include <stdio.h>
#define MAXSIZE 10 
//实现归并,并把最后的结果存放到Llist中 
void  merge(int *Llist, int Lsize,int *Rlist,int Rsize)
{	
	int i=0,j=0,k=0;
	int temp[MAXSIZE]; 
	while(i <Lsize && j<Rsize)
	{
		if(Llist[i] < Rlist[j])
		{
			temp[k++] =Llist[i++];
		}
		else
		{
			temp[k++] = Rlist[j++];
		}
	}
	while(i < Lsize)
	{
		temp[k++] =Llist[i++];		
	}
	while(j < Rsize)
	{
		temp[k++] =Rlist[j++];
	}
	int m;
	for(m=0;m<(Lsize+Rsize);m++){
		Llist[m]=temp[m];
		printf("%d ",Llist[m]);
	}
	printf("||\n");	
}

void merge_sort(int a[],int n)
{
	//拆分 
	int *Llist=a;
	int Lsize=n/2;
	int *Rlist=a+n/2;
	int Rsize=n-Lsize;
	if(n>1)
	{
		merge_sort(Llist, Lsize);
		merge_sort(Rlist, Rsize);
		merge(Llist, Lsize,Rlist, Rsize);
	}
}

int main(void)
{
	int i,a[10]={0,9,2,3,4,6,7,1,5,8};
	merge_sort(a, 10);
	for(i=0;i<10;i++)
		printf("%d ",a[i]);
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值