数组排序
冒泡排序
规则:
1、比较相邻的两个数
2、如果左边的大,则交换位置
3、向右移动一位,比较下一位
当所有的数都进行一遍这个规则时,得到最大的数放在最右边。然后重新回到最左端,循环剩下的N-1个数,依次循环。
选择排序:
规则:
1、指定一个数作为比较标准,跟其他数进行比较,得到最小的数
2、交换最小数和该标准数的位置
3、从剩下的数中,再选取一个数作为标准,依次和其它数比较,得到下一个最小数
4、交换该最小数和标准数的位置
5、重复第3~4步
插入排序:
图示:
奇偶排序:
规则:
1、把所有的奇数列的元素与其右相邻元素比较,交换大小,小的在左
2、把所有的偶数列的元素与其右相邻元素比较,交换大小,小的在左
3、循环前两步
java代码实现:
1 package com.luwen; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class Test2 { 7 8 public static void main(String[] args) { 9 10 OrderArray arr = new OrderArray(6); 11 12 arr.insert(12); 13 arr.insert(2); 14 arr.insert(10); 15 arr.insert(2); 16 arr.insert(5); 17 arr.insert(20); 18 19 arr.display(); 20 21 // arr.bubbleSort(); 22 // arr.display(); 23 24 // arr.selectSort(); 25 // arr.display(); 26 27 // arr.insertSort(); 28 // arr.display(); 29 30 arr.oddEvenSort(); 31 arr.display(); 32 } 33 } 34 35 36 class OrderArray{ 37 private long[] a; //数组 38 private int nElems; //数组下标 39 40 public OrderArray(int max){ 41 a = new long[max]; //初始化数组 42 nElems = 0; 43 } 44 45 /** 46 * 返回数组的长度 47 * @return 48 */ 49 public int size(){ 50 return nElems; 51 } 52 53 /** 54 * 添加数组元素 55 * @param value 56 */ 57 public void insert(long value){ 58 a[nElems] = value; 59 nElems++; 60 } 61 62 63 /** 64 * 冒泡排序 65 */ 66 public void bubbleSort(){ 67 for (int i = 0; i < nElems; i++) { // 外层循环 68 for (int j = 0; j < nElems-1-i; j++) { // 内层循环,每次循环找到一个最大值排在最后,排好的数不参与下次排序 69 if(a[j]>a[j+1]){ 70 // 互换位置 71 long k = a[j]; 72 a[j] = a[j+1]; 73 a[j+1] = k; 74 } 75 } 76 } 77 } 78 79 /** 80 * 选择排序 81 */ 82 public void selectSort(){ 83 // 挑出最小的数,放到第一个位置 84 int k; 85 for (int i = 0; i < nElems; i++) { 86 // 每次要比较的值的下标 87 k = i; 88 // 得到最小值 89 for (int j = i; j < nElems; j++) { 90 if(a[j]<a[k]){ 91 k = j; // 得到最小值的下标 92 } 93 } 94 // 交换位置 95 long v = a[k]; 96 a[k] = a[i]; 97 a[i] = v; 98 } 99 100 } 101 102 /** 103 * 插入排序 104 */ 105 public void insertSort(){ 106 for (int i = 1; i < nElems; i++) { 107 if(a[i]<a[i-1]){ 108 // 要求前面元素有序 109 // 将a[i] 插入到前面的j个元素中 110 for (int j = 0; j < i; j++) { 111 // 找出a[i]要插入的位置 112 if(a[i]<a[j]){ 113 long v = a[i]; 114 delete(i); 115 // 将a[j]往后移一位 116 for (int k = nElems-1; k > j; k--) { 117 a[k] = a[k-1]; 118 } 119 // 插入 120 a[j] = v; 121 } 122 } 123 } 124 } 125 126 // 方法二 127 /*for (int i = 1; i < nElems; i++) { 128 long temp = a[i]; 129 while(i>0 && a[i-1]>=temp){ 130 a[i] = a[i-1]; 131 --i; 132 } 133 a[i] = temp; 134 }*/ 135 136 } 137 138 /** 139 * 奇偶排序 140 */ 141 public void oddEvenSort(){ 142 for (int i = 1; i < nElems-1; i+=2) { 143 for (int j = 0; j < nElems-1; j+=2) { 144 if(a[i]>a[i+1]){ 145 long v = a[i]; 146 a[i] = a[i+1]; 147 a[i+1] = v; 148 } 149 if(a[j]>a[j+1]){ 150 long v = a[j]; 151 a[j] = a[j+1]; 152 a[j+1] = v; 153 } 154 } 155 } 156 } 157 158 /** 159 * 删除该位置上的值 160 * @param value 161 * @return 162 */ 163 public void delete(int index){ 164 List<Long> list = new ArrayList<Long>(); 165 for (int i = 0; i < nElems; i++) { 166 if(i!=index){ 167 list.add(a[i]); 168 } 169 } 170 long arr[] = new long[nElems]; 171 Object []obj = list.toArray(); 172 for (int i = 0; i < obj.length; i++) { 173 arr[i] = (long) obj[i]; 174 } 175 a = arr; 176 } 177 178 /** 179 * 查看数组 180 */ 181 public void display(){ 182 for (int i = 0; i < nElems; i++) { 183 System.out.print(a[i]+ " "); 184 } 185 System.out.println(""); 186 } 187 188 }
效率问题:
eg:10个随机数,
冒泡排序:
需要进行9+8+7+6+5+4+3+2+1=45次比较过程。
即. (N-1)+(N-2)+(N-3)+...+1 = N*(N-1)/2 当数据项很大时,比较次数近似为N^2/2,而交换次数为N^2/4(需不要需要交换是随机的,符合0-1分布),在大O表示法中,为O(N^2)。表示交换和比较的次数和数据项的平方成正比;数据项越大,比较耗时越大。
选择排序:
需要进行9+8+7+6+5+4+3+2+1=45次比较过程。但,只需要最多9次的交换。
当数据项很大时,次数成效率的主要因素,因此选择排序也是O(N2)时间。在N较小时,选择排序较快
插入排序:
需要进行1+2+3+4+5+6+7+8+9=45次比较
当数据部分有序时,方法二的while循环基本为假,这时插入排序只执行需要O(N)的时间