希尔排序&选择排序&时间复杂度分析

#include <stdio.h>
#include <stdlib.h>

void shellsort(char array[],int len);
void selectsort(char array[],int len);

void swap(char *a,char *b)
{
	*a ^= *b;
	*b ^= *a;
	*a ^= *b;
}//好多傻逼面试都考这种写法,岂不知这种写法在a,b是一个数时有bug:假设a=6,a=a^a=(0b110)^(0b110)=0,a=a^a=(0b000)^(0b000)=0,a=a^a=0(同上)
//或者

void swap1(char *a,char *b)
{
	*a += *b;
	*b -= *a;
	*a -= *b;
}//a=2a;a=a;a=0 bug一样存在
//所以多写一个temp不会死,并不是什么都能优化的

main()
{
	char c;
	int i=0,len=0;
	int test=6;
	char array[100];
	memset(array,0,100);
	while((c=fgetc(stdin))!=EOF)//&&c!='\n')
	{
		len++;
		array[i++]=c;
	}
//	shellsort(array,len);
	selectsort(array,len);
	for(i=0;i<len;i++)
		fputc(array[i],stdout);
	//swap(&test,&test);
	swap1(&test,&test);
	printf("\n%d",test);
}

void shellsort(char array[],int len)
{
	int gap,i,j;
	for(gap=len/2;gap>0;gap/=2)//3,3,4,1,4
	{
		for(i=gap;i<len;i++)//插入排序的一种简洁写法,好像是算法导论上的
		{
			for(j=i-gap;array[j+gap]<array[j]&&j>=0;j-=gap)
			{
				swap(&array[j+gap],&array[j]);
			}
		}
	}
}
void selectsort(char array[],int len)
{
	int i,j,min;
	for(i=0;i<len;i++)
	{
		min=i;
		for(j=i+1;j<len;j++)
		{
			if(array[j]<array[min])
			{
				min=j;
			}
		}
		if(min!=i)
		{
			swap(&array[i],&array[min]);
		}
	}
}
//选择排序时间复杂度分析:最好最坏情况最内层的循环平均执行N/2次(必须比较j和min处元素的值),外层循环执行N次,所以复杂度O(N^2)

下面说一说时间复杂度的分析方法:

这里把算法分为分治和非分治两种情况


1.非分治直接分析执行最多的代码次数,没有统一分析方法

以希尔排序为例子

这里分析原始的希尔排序,初始步长d=n/2,下一次步长d=d/2

第一次比较次数:1*n/2

第二次比较次数:最坏(1+2+3)*n/4

第三次比较次数:最坏(1+2+3+……+7)*n/8

......


2.分治有一种主定理方法

首先明确几个问题

A.f(n)=O(g(n))符号的定义:存在常量N和c,对于任意的n>N,0<=f(n)<=cg(n)

如:n^2=O(2 n^2)

说白了就是f一定是小于等于g或者大于g但是是和g同一个级别的无穷大量

若f(n)=O(g(n))则g=W(f)


B.f(n)=o(g(n))符号的定义:对于任意的c,存在常量N,对于任意的n>N,0<=f(n)<cg(n)其实这个g就是工科数学里面的相对于f的高阶无穷大

如:2n=o(n^2)

若f(n)=o(g(n))则g=w(f)     (omega打不出来只能用w了,抱歉)


C.主定理:

若T(n)=aT(n/b)+f(n),即规模为n的算法所用时间可以分治为a个规模n/b的同样问题加上一个f(n)

则有以下三个结论:

c1:f==O(n^(logb(a)-e))则T=O-n^(logb(a)

c2:f==O-(n^(logb(a)))则T=O-n^(logb(a)*log2(n)

c3:f==W(n^(logb(a)+e))则T=O-f原文中后面关于f那一坨基本上都满足


f=O里面有一横(g)表示同阶无穷大,定义为存在N,c1,c2,n>N时,c1*g<=f<=c2*g,夹逼定理

ps:图中那个x是不知道哪冒出来的



现在可以分析算法了,以快速排序为例子

最好情况下:均衡分治(为什么最好?别问我,看结果就知道,基于比较的比较次数都是W(nlog2(n))(证明见算法导论,利用决策树))
T(n)=2T(n/2)+ O(n)
主定理情况2
所以最好T= O(nlog2(n))

注意O被O包含

最坏情况下:最不均衡分治(为什么?不知道)
T(n)=T(1)+T(n-1)+ O(n)
T=n^2
次次都最不均衡则每次快排执行n步只确定一个元素的位置,确定n个需要n^2次

  • 9
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值