我在北京找工作(三):java实现算法<2> 直接插入排序+不可变类

来源:互联网 发布:用php写99乘法表思路 编辑:程序博客网 时间:2024/04/30 02:53

 

2013年9月3日 貌似看的排序算法实现的有点没难度,但还是一步一步稳扎稳打的来。

 

1、直接插入排序

直接插入排序(Insertion Sort)的基本思想:将数组分为有序区和无序区,每次将一个无序区的元素安琪关键字大小插入到有序区的适当位子,知道无序区元素个数为0,则排序完成。

同样的,我们设数组长度为N。
实现步骤:
<1> 初始时,下标为0的元素,也就是数组中的第一个元素自成有序区,其余皆为无序区元素。
<2> 将无序区的第一个元素插入到当前有序区的适当位置中,有序区间长度+1
<3> 重复第<2>步,直到无序区元素个数为0,则排序完成!

还是一些严格按照定义步骤进行编写的代码(依旧是默认为从小到大排序)........:

//直接插入排序基础版public void insertSort(int[] arr) {int j=-1;int k=-1;//循环默认从arr[1]开始排序,因为默认初始时arr[0]自成有序区for(int i=1;i<arr.length;i++) {//j控制循环层 为arr[i]在当前有序区为之寻找一个合适的插入位子for(j=i-1;j>=0;j--) {if(arr[j]<arr[i]) break ;}//如果找到了一个合适的位子,并且不是当前元素的正前方一个if(j!=i-1) {//将有序区中插入位子之后的所有元素向后移动,腾出空间int temp = arr[i] ;for(k=i-1;k>j;k--) {arr[k+1]=arr[k] ;}//最后将arr[i]放到正确的位子上即可arr[k+1] = temp ;}}}


不知道读者有没有注意到,前面的代码只是严格按照直接插入排序的定义来编写的,一步一步的实施,虽然次序井然有序。而且也明确的分工流水线。但是如此冗长的代码,依旧是不够清晰的!能够对其进行改写的方法有很多:
1)我们完全可以将搜索和后面的元素后移这两步进行同步操作(这里所说的同步和系统级别的线程级别的同步完全没有关系),h合并为一个步骤。
即,向前搜索一个,比之大的就直接后移一个位子。一边搜索,一边后移。这样之后,当找到合适的位子之后只需要直接插入就行了!!!

下面给出实现:

//合并搜索和移位的直接插入排序public void insertSort2(int[] arr) {int j= -1;for(int i=1;i<arr.length;i++) {if(arr[i]<arr[i-1]) {int temp = arr[i] ;//一边搜索+同时右移元素for(j=i-1;j>=0&&arr[j]>temp;j--) {arr[j+1] = arr[j] ;}//找到位子,直接插入元素arr[j+1] = temp ;}}}


可以看到,代码简单了许多。如果对于一些想要死记硬背的记住排序代码的屌来说,这可是难记了很多,但是对于通过原理摸索实现的猿们,这同样是轻松了许多。
所以还是不可不强调,通晓原理,才是学习的最好方法!!! 

 别再抱怨啦,,,,,啦啦啦   德玛西亚~~~

还有一种改写方法,是看别人的代码是想到的:
2)原理很简单,就是在前一种的基础上,用元素交换代替掉元素右移。
代码嘛? 小二在这里就不给了,读者们自己也该去敲敲代码了,每天敲敲代码,神清气爽,倍儿爽!   哈哈~~~@

下面想说的一点就是半个月前看到的别人问的一个问题,于是去网上看了一些资料。有个概念叫“不可变类”。

2、不可变类
java自带的如:String、还有其余包装类Integer、Double都是不可变类。所谓不可变,简单的说就是其在创建对象之后,其属性值将不能在对象层面上发生改变。
如果要改变它的值,那肯定就是另外一个对象了。不知道这样通俗的理解会不会引来 嘲讽 0.0
这也是一个面试时可能会接触的知识点,所以直接上代码掩演示了:

package net.mldream;public final class NoChangeClass {/* * 如何创建一个不可变类 四步骤 *///1、所有成员都是Private的private String userName ;private int[] myArray ;//2、不对外提供对成员进行改变的方法,如setUserName(..)、setMyArray(..)等//3、确保所有的类方法都不能被重载,有两种方法。//一:使用final Class(强不可变类)//二:将该类的所有方法加上final(弱不可变类)public String toString() { StringBuffer sb = new StringBuffer("This is : ");sb.append(this.userName+" Number are:") ;for (int i = 0; i < myArray.length; i++) { sb.append(myArray[i] + " ");}return sb.toString();}//4、如果类的某一个成员变量不是原始类型(primitive)或者不可变类,//则必须通过在成员初始化(in)或get方法(out)时通过深度复制(clone)方法,确保类的不可变public NoChangeClass(int[] myArray,String userName) {this.myArray = myArray.clone();this.userName = userName ;}public static void main(String[] args) {}}


有兴趣的读者一定要自己去试试,并且能够很好的理解通透其中的原理实现。 如果有什么不理解的,也可以来和我交流。。
欢迎欢迎~~~~~   今天就到这里吧~  Good Good study,Day Day up!