java编程排序之内置引用类型的排序规则实现,和自定义规则实现+冒泡排序运用

时间:2022-12-15 06:41:35

第一种排序:【冒泡排序】基本数据类型的排序。

【1】最简易的冒泡排序。效率低。因为比较的次数和趟数最多。

 /**
* 最原始的冒泡排序。
* 效率低。
* 因为趟数和次数最多。都是按最大化的循环次数进行循环
* @Title: sort
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param arr
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-5 上午8:42:45
*/
public static void sort(int[] arr){
//要走arr.length-1趟
for(int i=0;i<arr.length-1;i++){
System.out.println("第"+(i+1)+"趟");
for(int j=0;j<arr.length-1;j++){ if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp; }
System.out.println("第"+(j+1)+"次"+Arrays.toString(arr));
}
}
System.out.println("TestSort.sort01()"+Arrays.toString(arr));
}

【2】进行一次优化的冒泡排序。减少每趟的比较次数。

 /**
* 冒泡排序,减少每趟比较的次数.
* 每一趟都能找到数列中相对最大的一个数。
* 而每一次,都是进行数列中每两个相邻的数进行比较。需要比较数列长度-1次。才能完成一趟。
* 由于每一趟都找出一个最大数,所以,找出的最大数,就不用再比较了,因此每一趟的比较次数就随着趟数的增加而减少。
* @Title: sort01
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param arr
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-4 下午8:37:45
*/
public static void sort01(int[] arr){
//要走arr.length-1趟
for(int i=0;i<arr.length-1;i++){
System.out.println("第"+(i+1)+"趟");
for(int j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
System.out.println("第"+(j+1)+"次"+Arrays.toString(arr));
}
}
System.out.println("TestSort.sort01()"+Arrays.toString(arr));
}

【3】进行最终的优化。减少比较的趟数和次数

     /**
* 冒泡排序。最终版,减少趟数并且也减少每趟的次数
* @Title: sort02
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param arr
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-4 下午8:52:59
*/
public static void sort02(int[] arr){
//建立一个标示。如果数列已经排序完毕,则跳出循环,提高效率
boolean flag=true;
for(int i=0;i<arr.length-1;i++){
System.out.println("第"+(i+1)+"趟");
flag=true;
for(int j=0;j<arr.length-1-i;j++){ if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
//如果有相邻数字互换位置,说明数列还没有排好序,则将标示改成false,不让跳出循环
flag=false;
}
System.out.println("第"+(j+1)+"次"+Arrays.toString(arr));
} //在某一趟,已经没有相邻数据交换位置,说明,顺序已经排好,则跳出本层循环
if(flag){
break;
} }
System.out.println("TestSort.sort02()"+Arrays.toString(arr));
}

break,continu,return的区别:

break---->用于终止break所在的本层循环,对本层循环后边同层相邻的代码无影响,会执行后边的代码。

continu-->用于暂停本次循环,不执行continu后边循环体内的代码,继续下次循环。

return--->用于返回方法。无论多少层循环,无论处于什么位置,一旦执行到return,则方法终止运行。后边的代码,无论本层,还是他层,一概不执行。

第二种排序:引用数据类型的排序。

 【A】[内置引用类型(String Date Integer等),自定义引用类型]

 实现步骤:(1)实现一个接口。java.lang.Comparable

      (2)重写一个方法public int compareTo(Object obj)

      (3)返回 0 表示 this=obj

        返回 正数 表示this>obj

        返回 负数 表示 this<obj

第一种:常用内置类的比较规则

    [1]Integer --->首先将两个包装类,转换成基本数据类型。然后进行大小比较。
        [2]Character---> 字符类比较规则是:先将两个字符转换成对应的unicode值,然后进行相减。从而比较大小。
        [3]String
            ---->从两个字符串的第一个字符开始,逐个对应字符进行比较,如果遇见字符不同,返回字符的unicode码之差,后边字符不在对比,比较。决定两个字符串的大小。
            ---->如果一个字符串是另一个子符串的起始子字符串,则进行长度差比较。比如:abc.compareTo(abcde)进行比较,返回-2
        
        [4]Date--->将两个时间都转换成长整形数,然后比较两个数的大小。决定谁大谁小

                 Integer a;//首先将两个包装类,转换成基本数据类型。然后进行大小比较。
public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
} //字符类比较规则是:先将两个字符转换成对应的unicode值,然后进行相减。从而比较大小。
Character adCharacter;//字符的排序规则:
public int compareTo(Character anotherCharacter) {
return this.value - anotherCharacter.value;
} String aString;
//字符串的比较规则
//(1)从两个字符串的第一个字符开始,逐个对应字符进行比较,如果遇见字符不同,返回字符的unicode码之差,后边字符不在对比,比较。决定两个字符串的大小。
//(2)如果一个字符串是另一个子符串的起始子字符串,则进行长度差比较。比如:abc.compareTo(abcde)进行比较,返回-2
public int compareTo(String anotherString) {
int len1 = count;
int len2 = anotherString.count;
int n = Math.min(len1, len2);
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset; if (i == j) {
int k = i;
int lim = n + i;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
} else {
while (n-- != 0) {
char c1 = v1[i++];
char c2 = v2[j++];
if (c1 != c2) {
return c1 - c2;
}
}
}
return len1 - len2;
} //比较规则:将两个时间都转换成长整形数,然后比较两个数的大小。决定谁大谁小
Date aDate;
public int compareTo(Date anotherDate) {
long thisTime = getMillisOf(this);
long anotherTime = getMillisOf(anotherDate);
return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
}

【B】[jdk内置引用类型性,自定义比较规则]

  实现步骤:(1)实现一个接口。java.util.Comparator

      (2)重写一个方法public int compare(String o1, String o2)

      (3)返回 0 表示 o1=o2

        返回 正数 表示o1>o2

        返回 负数 表示 o1<o2

  内置引用类型实现java.lang.Comparable接口定义比较规则和自定义规则实现java.util.Comparator接口的不同之处和区别

 /**
* 自定义对象的比较规则:实现的是java.util.Comparator接口
* 【1】可以作为一个独立的比较器,进行两个对象之间按某种自定义的规则比较
* 【2】可以作为一个工具
*/ public class MyCompa2 implements java.util.Comparator<String>{
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
//自定义规则
return 0;
} /**
* jdk内置类的比较规则,实现java.lang.Comparable接口
* 【1】本类对象的比较器,私有化。
*
*
*/
public class MyCompa implements Comparable<String> { @Override
public int compareTo(String obj) {
// TODO Auto-generated method stub
//写比较规则的代码
//return :正数 this>obj 0 this==obj 负数 this<obj
return 0;
}

封装的一个排序工具类,结合了冒泡排序和内置类排序规则和自定义排序规则。代码示范

 /**
* 公共的比较器。自定义字符串的比较规则。按字符串长度进行比较
* @ClassName: MyCompa2
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 尚晓飞
* @date 2014-8-6 下午6:47:32
*
*/
public class MyCompa2 implements java.util.Comparator<String>{
/**
* 自定义两个字符串的比较规则:按长度大小的比较
* @Title: compare
* @Description: TODO(这里用一句话描述这个方法的作用)
* @author 尚晓飞
* @date 2014-8-6 下午6:49:17
* @param o1
* @param o2
* @return
* @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
*/
@Override
public int compare(String o1, String o2) {
// TODO Auto-generated method stub
int a=o1.length();
int b=o2.length();
return a-b;
}
/**测试该比较器的方法。
* String[] str=new String[]{"abcdef","adc","abcde","abf","ab","a"};
CompareUtil.sort2(str, new MyCompa2());
System.out.println(Arrays.toString(str));
打印结果:[a, ab, adc, abf, abcde, abcdef]
*/ } /**
* 排序工具类 包括:内置引用类,自身的排序规则
* 内置引用类简单的自定义排序规则
* @ClassName: CompareUtil
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 尚晓飞
* @date 2014-8-6 下午7:46:18
*
*/
public class CompareUtil {
/**
* 对容器进行排序+自定义的排序规则
*
*泛型方法的规则
* 【访问修饰符】 +【静态,非静态修饰符】+泛型+【返回值类型】+方法名(带泛型的参数列表){}
*
* @Title: sort3
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param list
* @param comparator
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-6 下午7:09:54
*/
public static <T> void sort3(List<T> list,Comparator<T> comparator){
//将容器转换成数组
Object[] arr=list.toArray();
//对转换成的数组进行排序
sort2(arr, new MyCompa2());
//将排好序的容器中的元素,按顺序重新放入容器
for(int i=0;i<arr.length;i++){
list.set(i, (T)arr[i]);
}
} /**
* 自定义规则的比较器。对字符串进行长度的排序(升序排列)
* MyCompa2是自定义规则的比较器
* @Title: sort2
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param arr
* @param myCompa2
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-6 下午6:52:19
*/
public static <T> void sort2(Object[] arr,Comparator<T> comparator){
for(int i=0;i<arr.length-1;i++){
boolean flag=true;
for(int j=0;j<arr.length-1-i;j++){
//进行比较
if(comparator.compare((T)arr[j], (T)arr[j+1])>0){
Object temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag=false;
}
} if(flag){
break;
}
}
} /**
*常用jdk内置引用类型的数据,进行升序排序
* @Title: sort
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param obj
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-5 下午8:06:43
*/
public static void sort(Object[] obj){
for(int i=0;i<obj.length-1;i++){
boolean flag=true;
for(int j=0;j<obj.length-1-i;j++){
//进行比较
if(((Comparable)obj[j]).compareTo(obj[j+1])>0){
Object temp=obj[j];
obj[j]=obj[j+1];
obj[j+1]=temp;
flag=false;
}
} if(flag){
break;
}
}
} /**
* 使用泛型方法进行排序(升序)
* @Title: sort2
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param obj
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-5 下午8:25:02
*/
public static <T extends Comparable<T>> void sort2(T[] obj){
for(int i=0;i<obj.length-1;i++){
boolean flag=true;
for(int j=0;j<obj.length-1-i;j++){
//进行比较
if(((Comparable)obj[j]).compareTo(obj[j+1])>0){
T temp=obj[j];
obj[j]=obj[j+1];
obj[j+1]=temp;
flag=false;
}
} if(flag){
break;
}
} } /**
* 对list容器进行排序(升序)
* @Title: sort3
* @Description: TODO(这里用一句话描述这个方法的作用)
* @param list
* @return void 返回类型
* @author 尚晓飞
* @date 2014-8-5 下午8:29:44
*/
public static <T extends Comparable<T>> void sort3(List<T> list){
//将list容器转换成数组
Object[] objects=list.toArray();
//对数组进行排序
CompareUtil.sort(objects);
//改变容器中对应的值
for(int i=0;i<objects.length;i++){
list.set(i, (T)objects[i]);
} } public static void main(String[] args) {
String[] aStrings={"dfb","cmd","bdsf","addf"}; CompareUtil.sort(aStrings);
System.out.println(Arrays.toString(aStrings));
}
}

 java.util包中有一个Collections工具类对list容器进行排序。测试代码。

 import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
* java.util包中提供了一个工具类Collections对集合的排序
* 一种:使用jdk内置的排序规则(升序)
* 二种:使用java.utli.Comparator接口,重写方法,自定义排序规则
* @ClassName: Demo5
* @Description: TODO(这里用一句话描述这个类的作用)
* @author 尚晓飞
* @date 2014-8-6 下午8:07:18
*
*/
public class Demo5 {
public static void main(String[] args) {
// public static <T extends Comparable<? super T>> void sort(List<T> list)
//容器工具类,提供的排序方法一。规则,是jdk内部规则
List<Integer> list=new ArrayList<Integer>(); list.add(10);
list.add(9);
list.add(8);
System.out.println(Arrays.toString(list.toArray()));//排序前,打印结果[10, 9, 8]
Collections.sort(list);
System.out.println(Arrays.toString(list.toArray()));//排序后,打印结果[8, 9, 10] //public static <T> void sort(List<T> list, Comparator<? super T> c)
//容器工具类,提供的排序方法二.规则,自定义的。java.util.Comparator
List<String> list2=new ArrayList<String>();
list2.add("abcdef");
list2.add("abcde");
list2.add("abcd");
list2.add("abc");
list2.add("ab");
list2.add("a");
System.out.println(Arrays.toString(list2.toArray()));//排序前:打印结果[abcdef, abcde, abcd, abc, ab, a]
Collections.sort(list2, new MyCompa2());
System.out.println(Arrays.toString(list2.toArray()));//排序后:打印结果[a, ab, abc, abcd, abcde, abcdef] } }