天天看点

死宅日志——排序和进制

一个假期过去了 我觉得我不能这么堕落所以要回顾一下所学的东西再自学点东西并记录一下:

今天回顾了一下进制和排序

先说进制吧:
	进制的概念在这里我就不说了,我就说一下进制的转换,以十进制和六进制为例。10进制就是满10进1,6进制就是满6进1。
例如:
235 十进制的235=2*10^2+3*10^1+5,而六进制的235=2*6^2+3*6+5=95。由于我们习惯于用十进制来计算,这就直接由六进制转换成十进制了。
十进制转换六进制有两种方法:
1、6的指数幂有1、6、36、216而95明显没有216大且95里有2个36余23。so其百位为2,同理23里有3个6余5其十位为3个位为5。得235。
2、95除以6得15余5所以个位为5,15除以6得2余3。是以最终得235。
           

进制就这样吧,现在来说排序这里就我今天就看了冒泡、插入、选择三种。

先说冒泡(bubble):
	若存在i总有a[i]>=a[i+1](i<n)我们是不是可以认为它排过序了?所以将a[i]与a[i+1]比较若逆序则交换 
	如:
		53 33 19 53 3 63 82 20 19 39
		33 19 53 3 53 63 20 19 39 82
		19 33 3 53 53 20 19 39 63 82
		19 3 33 53 20 19 39 53 63 82
		3 19 33 20 19 39 53 53 63 82
		......
		3 19 19 20 33 39 53 53 63 82
	我们来分析一下,第一趟后最后的那个数必定是最大那一个。同理,第二趟后倒数第二个就是第二大的。所以我们可以看出m趟后我们可以只排前n-m的序而不用管后m个数。
	代码:
	for(int i=1;i<n;i++)
	{
		bool f=false;//是否排好序
		for(int j=1;j<=n-i;j++)
		if(a[j]>a[j+1]){int t=a[j];a[j]=a[j+1];a[j+1]=t;f=true;}
		if(f==false)break;
	}
	如图:
           
死宅日志——排序和进制

y是值 x是位置

选择(selection):
	思想很简单,在没有顺序的数列中挑出最小的那一个。
	如:
		12 5 1 9 13 83 2
		1 5 12 9 13 83 2
		1 2 12 9 13 83 5
		1 2 5 9 13 83 12
		......
		1 2 5 9 12 13 83
	我们可以看到前i-1个已经不用管了只需排后n-i+1个的序就行了
	代码:
	for(int i=1;i<n;i++)
	{
		int f=i;//最小的那一个
		for(int j=i+1;j<=n;j++)
		if(a[k]>a[j])k=j
		if(k!=i){int t=a[k];a[k]=a[j];a[j]=t;};
	}		
	也可以是
	for(int i=1;i<n;i++)
		for(int j=i+1;j<=n;j++)
		if(a[i]<a[j]{int t=a[k];a[k]=a[j];a[j]=t;};
	如图:
           
死宅日志——排序和进制

y是值 x是位置

插入(insertion)
如:
	21 54 5 63 1 3 8
	5 21 54 63 1 3 8
	1 5 21 54 63 3 8
	1 3 5 21 54 63 8
	1 3 5 8 21 54 63
代码:
	int f;
	for(int i=2;i<=n;i++)//前i个已经排好
	{
		f=a[i];//要插入的那个
		for(;a[j]>=f;j--)a[j]=a[j+1]//寻找插入的地方
		a[j+1]=f;
	}	
           
死宅日志——排序和进制

现在来分析一下假设情况最糟糕的时候,冒泡要循环n-1的累加和次 选择也要循环n-1的累加和次,插入也要循环n-1的累加和次。也就是说他们的时间复杂度基本是一样的。

继续阅读