1 package test; 2 3 import java.nio.channels.SelectableChannel; 4 5 import com.itqf.bean.User; 6 7 public class cTypeCode { 8 9 /********************************************希尔排序和插入排序*******推荐严慧敏的那本数据结构,思想步骤我都加入到算法里面了,很精简了*********************************************************** 10 * 插入排序 11 * 12 * @param values 13 * 带排序数组 14 */ 15 public void insertSort(int[] values) { 16 int mod;// 中间值 17 for (int i = 1; i < values.length; i++) { 18 mod = values[i];// 记录初始位置的值,完成交换 19 int index = 0;// 记录位置 20 for (int j = i; j >= 1; j--) { 21 // 如果前面的值比后面的值小,就后 移 22 if (values[j - 1] > mod) { 23 values[j] = values[j - 1]; 24 } else { 25 index = j; 26 break; 27 } 28 } 29 values[index] = mod; 30 } 31 32 } 33 34 /** 35 * shell sort 36 * 希尔排序是对插入排序的一个改进,相隔几个增量的递进式排序,直到增量为1。。所有的增量必须只能被1除。 37 * @param values 38 * valuies which wait for sroted 39 * @param dk 40 * added values 41 */ 42 public void shellSort(int[] values, int dk) { 43 if (dk > values.length) { 44 System.out.println("values is beyond the binder"); 45 return; 46 } 47 // * 1.使用增量循环遍历数组 48 for (int i = dk; i < values.length; i++) { 49 // * 2.创建保留初始比较值得变量,创建保存比较值的下标值的变量 50 int mod = values[dk]; 51 int index = 0; 52 // * 3.遍历后面已经排好序的序列,退出循环 53 for (int j = i; j >= dk; j -= dk) { 54 // 在合适的地方插入比较值,如果比较值小于当前值,就交换, 55 if (values[j - dk] > mod) { 56 values[j] = values[j - dk]; 57 } else { 58 // 否则,记下比较值的下标,进行交换, 59 index = j; 60 break; 61 } 62 } 63 // 4.在下标处填入初始比较值,第一轮比较完成 64 values[index] = mod; 65 } 66 } 67 68 /********************快速排序分割线*********************************************************************************** 69 * 快速排序方法 为什么会采用这种归位那,因为始终是在和枢轴进行比较,就没有必要进行枢轴的交换了。 70 * 71 * @param values 72 * 待排序数组 73 * @param low 74 * 最低位下标 75 * @param high 76 * 最高位下标 77 */ 78 public static int quickSort(int[] values, int low, int high) { 79 // 1.确定枢轴,以第一个为枢轴 80 // 1.1 为了提高性能,采用三者取中方法,可大大提高乱序情况下的性能 81 int pivotKey; 82 int[] keys = { values[low], values[high], values[(low + high) / 2] }; 83 pivotKey = keys[0]; 84 for (int i = 0; i < keys.length - 1; i++) { 85 if (pivotKey < keys[i]) { 86 pivotKey = keys[i]; 87 } 88 } 89 // 2.循环数组 90 while (low < high) { 91 // 2.1 依最高位下标递减检查小于枢轴的关键字,和low交换 92 while (low < high && values[high] >= pivotKey) 93 --high; 94 // 2.2 把高位赋值给低位 95 values[low] = values[high]; 96 // 3.从最低位开始依次递增检查大于枢轴的关键字,和high交换 97 while (low < high && values[low] <= pivotKey) 98 ++low; 99 // 把低位赋值给高位 100 values[high] = values[low]; 101 // 4.重复2和3步骤 102 } 103 // 5.枢轴归位 104 values[low] = pivotKey; 105 // 6.返回枢纽位置 106 return low; 107 108 } 109 110 /** 111 * 快速排序完整部分 112 * 113 * @param values 114 * @param low 115 * @param high 116 */ 117 public static void overrallSort(int[] values, int low, int high) { 118 if (low < high) { 119 int index = quickSort(values, low, high);// 获得枢轴下标,把数组一分为二 120 // 枢轴左半部排序 121 overrallSort(values, low, index - 1); 122 // 枢轴右半部排序 123 overrallSort(values, index + 1, high); 124 } 125 } 126 127 /** 128 * 选择排序 129 * 130 * @param values 131 */ 132 public static void selectSort(int[] values) { 133 for (int i = 0; i < values.length - 1; i++) { 134 for (int j = i; j < values.length; j++) { 135 if (values[i] > values[j]) { 136 // 交换关键字 137 int mad = values[i]; 138 values[i] = values[j]; 139 values[j] = mad; 140 } 141 } 142 } 143 144 } 145 146 /****************************************************大顶堆排序算法************************************ 147 * 堆排序 148 * @param a 149 * @param b 150 * @return 151 */ 152 public boolean isBig(int a, int b) { 153 if (a < b) { 154 return false; 155 } 156 return true; 157 } 158 159 /** 160 * 此部分算法,视为最简洁堆排序算法。比网上大部分都要好,但是难理解,把这个算法理解了,你会发现很简洁的算法。 161 * @param values 162 * @param start 163 * @param high 164 */ 165 public void heapAdjust(int[] values, int start, int high) { 166 int rc = values[start]; 167 for (int i = 2 * start; i <= high; i *= 2) {// 沿着key较大的孩子节点向下筛选 168 if (i < high && !isBig(values[i], values[i + 1])) {// i为较大的记录的下标 169 i++;// 如果i是小的记录,就把i加一,变为沿着另一个子节点向下跑 170 } 171 if (isBig(rc, values[i])) {//如果rc大于最大的子节点,就把rc插入到start的位置,也就是父节点,然后这一部分的堆排序结束 172 break;// rc应该插入到s位置上 173 } 174 values[start] = values[i];//rc不大于最大的子节点,就把最大的子节点放到父节点的位置,进行下一次循环堆排序 175 start = i;//沿着key值最大的节点向下筛选 176 } 177 values[start] = rc;// 插入,也可以理解为归位 178 } 179 180 public void heapSort(int[] values) { 181 /** 182 * 堆排序要解决两个问题。 第一,如何由无序序列建成一个堆 第二,如何在输出堆顶元素之后,调整剩余元素成为一个新的堆 现在建立大根堆 183 */ 184 for (int i = (values.length - 1) / 2; i >= 0; i--) { 185 heapAdjust(values, i, values.length - 1); 186 } 187 for (int i = values.length - 1; i > 0; i--) { 188 // 交换堆顶最大值和最后一个记录 189 int mad = values[0]; 190 values[0] = values[i]; 191 values[i] = mad; 192 heapAdjust(values, 0, i - 1); 193 } 194 } 195 196 /***********************************************************************归并排序算法分割线********************************************* 197 * 归并部分排序算法 198 * 199 * @param values 200 * @param low 201 * @param mad 202 * @param high 203 */ 204 public static void merge(int[] values, int low, int mad, int high) { 205 int[] tr = new int[high + 1];// 辅助序列 206 int low1 = low; 207 int high1 = high; 208 int i; 209 int j = mad + 1; 210 // * 第一步:循环整个序列,分为两部分进行比较,数值大的加入到辅助序列中,重复此步骤 211 for (i = low; low <= mad && j <= high; i++) { 212 if (values[low] > values[j]) { 213 tr[i] = values[low++]; 214 } else { 215 tr[i] = values[j++]; 216 } 217 } 218 // * 第二步,把还有剩余的部分加入到辅助序列中 219 if (j <= high) { 220 tr[i] = values[j++]; 221 } 222 if (low <= mad) { 223 tr[i] = values[low++]; 224 } 225 // * 第三步:把辅助序列中排好序的序列恢复到原先的存储中 226 // 把排序好的序列恢复到原序列中 227 for (int j2 = low1; j2 <= high1; j2++) { 228 values[j2] = tr[j2]; 229 } 230 231 } 232 233 /** 234 * 归并排序 235 * @param values 236 * @param low 237 * @param high 238 */ 239 public static void mSort(int[] values, int low, int high) { 240 if (low == high) {// 如果相等,就返回 241 return; 242 } else { 243 int mad = (low + high) / 2; 244 mSort(values, low, mad); 245 mSort(values, mad + 1, high); 246 merge(values, low, mad, high); 247 } 248 } 249 250 251 /**************************************************************************************简单哈希算法分割线************************************************* 252 * 在hash表中查找指定值 253 * 首先看一下,用hash函数得出来的hash地址位置上是否有值并且和要查找的值相等,如果相等,就返回,如果不相等,就继续查找下一个。、 254 * 不为空和不相等,同时成立,才会有找下去的必要,其他情况没有必要找下去。比如,位置为空,就可以直接退出了。 255 * 256 * @param hashTable 257 * @param value 258 */ 259 public boolean searchHash(int[] hashTable, int value) { 260 // 计算hash值 261 int hashCode = getHashCode(value, hashTable.length); 262 // 检测用hash函数得出来的hash地址位置上是否有值并且和要查找的值相等,两者都不想等,继续查找。找到退出循环 263 // 不为空和不相等,同时成立,才会有找下去的必要,其他情况没有必要找下去。比如,位置为空,就可以直接退出了。 264 while (hashTable[hashCode] != 0 && hashTable[hashCode] != value) { 265 hashCode++; 266 } 267 // 找到就返回成功 268 if (hashTable[hashCode] == value) { 269 return true; 270 } 271 return false; 272 273 } 274 275 /** 276 * 计算hash值 277 * 278 * @param value 279 * 关键字 280 * @param length 281 * hash表长度 282 * @return 283 */ 284 public int getHashCode(int value, int hashLength) { 285 286 return value % hashLength; 287 288 } 289 290 public static void main(String[] args) { 291 292 // TODO Auto-generated method stub 293 294 int[] values = { 12, 8, 2, 3, 4, 78, 96, 52 }; 295 // 296 // //overrallSort(values, 0, values.length-1); 297 // //int index = quickSort(values, 0, values.length-1); 298 // selectSort(values); 299 // System.out.println(index); 300 301 302 // user.heapSort(values);堆排序 303 mSort(values, 0, values.length - 1);// 归并排序 这个归并排序有点问题,最后一个为什么是0,我看不出来,有看出来的,请回答,谢谢。 304 for (int i = 0; i < values.length; i++) { 305 System.out.print(values[i] + " "); 306 } 307 } 308 }