C语言第六次上机实验

 时间复杂度 -插入,选择,冒泡,O(n2) --归并O(nlogn)

插入排序:先对数列最左2个数据排序,再把第三个加进来..接着第四个......

代码实现:

#include<stdio.h>
int main(void)
{
	int len,i,j,Q;//Q为标记,
	scanf("%d",&len); 
	int arr[len];
	for(i=0;i<len;i++)scanf("%d",&arr[i]);
	for(i=1;i<len;i++)
	{
		Q=arr[i];//要插入的元素
		for(j=i-1;j>=0;j--) 
		{
			if(arr[j]>Q)
				arr[j+1]=arr[j];//Q之前的都是有序的,所以,就是找一个比Q小的,或者没有,
			else break;//找到了 
		}
		arr[j+1]=Q;
	}
	for(i=0;i<len;i++)printf("%d\n",arr[i]);
	
}

简而言之就是不断的把一个个元素加到之前已经排好的有序数列中去;






选择排序:先第一个元素和之后所以元素比较,遍历,符合条件就交换;再第二个元素和之后的所以元素遍历比较..依次..

代码实现:

for(i=0;i<len;i++)
	
	for(j=i+1;j<len;j++)
		
		if(arr[i]>arr[j])   //如果前面的比后面的大,两者交换 
		{
			temp=arr[i];
			arr[i]=arr[j];
			arr[j]=temp;
		}
	

懒了,没写全,






冒泡排序: 选择排序是 第一个点不动,和后面遍历比较,第二个点不动..依次.而冒泡则是,第一个和第二个比.大的往后,第二个和第三个比,,大的往后..依次,感觉就像是把大的泡往后面推..

代码实现

#include<stdio.h>
int main(void)
{
	int i,j,len,temp;
	scanf("%d",&len);
	int arr[len];
	
	i=len;        //获取数据 
	while(i--)scanf("%d",&arr[len-i-1]);
	 
    for(i=0;i<len-1;i++)
    	for(j=0;j<len-1-i;j++)
    		if(arr[j]>arr[j+1])
    		{
	    		temp=arr[j];
	    		arr[j]=arr[j+1];
	    		arr[j+1]=temp;
	    	}
    	for(i=0;i<len;i++)printf("%d\n",arr[i]);
}

这里有一个简单的优化方法,就是一次下来没有发生一次交换,那就直接结束排序;







合并排序:适合规模比较大的排序,递归形式:递归体-(把整个数组一分为二,对左数组排序,对右数组排序,合并);

代码实现:

#include<stdio.h>
#include<stdlib.h>
void sort(int arr[],int left,int right);
void merge(int arr[],int left,int right);
int main(void)
{
	int n;
	scanf("%d",&n);
	int arr[n];
	for(int i=0;i<n;i++)scanf("%d",&arr[i]);
	sort(arr,n/2,n-n/2);
	for(int i=0;i<n;i++)printf("%d\n",arr[i]);
	return 0;
}

void sort(int arr[],int left,int right)
{
	
	if(left>1){
		sort(arr,left/2,left-left/2);
		sort(arr+left,right/2,right-right/2);
		merge(arr,left,right);
	}
	if(left==1)
		{
			if(right==2){
				merge(arr+1,1,1);
				merge(arr,1,2);
				
			}
			else merge(arr,1,1);
		}
	
}

void merge(int arr[],int left,int right)
{
	int vleft,vright;
	int i,j,k;i=j=k=0;
	int *p=(int *)malloc((left+right)*sizeof(int));
	while(i<left&&j<right)
	{
		if(arr[i]<arr[j+left])
			{
				*(p+k)=arr[i];
				i++;
				k++;
				
			}
		else {
			*(p+k)=arr[j+left];
			j++;k++;
		}
	}
	if(i==left)
		{
			while(j<right){
				*(p+k)=arr[j+left];
				j++;k++;
			}
		}
		if(j==right)
		{
			while(i<left){
				*(p+k)=arr[i];
				i++;k++;
			}
		}
	for(i=0;i<left+right;i++)arr[i]=*(p+i);
}

还是新手..递归体那里还不够简练...敲代码的时候,有一个括号括错地方了,语法没错只是逻辑错了..最讨厌了.....debug了好久....郁闷死了....

还有几个排序,:希尔排序,堆排序,快速排序...之类的,以后再去写吧...


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值