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!