[关闭]
@snail-lb 2017-02-28T15:17:28.000000Z 字数 12095 阅读 717

经常查询的代码

代码


一、二叉树

  1. package com.cn;
  2. import java.lang.reflect.Array;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. public class BinaryTree<E> {
  6. /** 根节点 **/
  7. Node<E> rootNode;
  8. /** 树深度 **/
  9. int depth;
  10. class Node<E> {
  11. /** 节点数据 **/
  12. E date;
  13. /** 左子树 **/
  14. Node<E> left;
  15. /** 右子树 **/
  16. Node<E> right;
  17. Node(E date) {
  18. this.date = date;
  19. this.left = null;
  20. this.right = null;
  21. }
  22. Node(E date, Node<E> left, Node<E> right) {
  23. this.date = date;
  24. this.left = left;
  25. this.right = right;
  26. }
  27. }
  28. public BinaryTree() {
  29. }
  30. /**
  31. * 使用数组构造一个完全二叉树
  32. *
  33. * @param o
  34. */
  35. public BinaryTree(E[] o) {
  36. this();
  37. Node<E> root = null;
  38. this.rootNode = createFullBinaryTree(root, o, 0);
  39. }
  40. /**
  41. * 创建满二叉树函数
  42. *
  43. * @param root
  44. * @param o
  45. * @param index
  46. * @return
  47. */
  48. private Node<E> createFullBinaryTree(Node<E> root, E[] o, int index) {
  49. if (index >= o.length) {
  50. return null;
  51. }
  52. root = new Node<E>(o[index]);
  53. // 数组是从0开始的,所以左节点的序号为父节点的两倍多一个,右节点为父节点的两倍多两个
  54. root.left = createFullBinaryTree(root.left, o, 2 * index + 1);
  55. root.right = createFullBinaryTree(root.right, o, 2 * index + 2);
  56. return root;
  57. }
  58. /**
  59. * 前序遍历输出数组
  60. *
  61. * @return E[]
  62. */
  63. public E[] preorderTraversal(Node<E> node) {
  64. List<E> list = new ArrayList<E>();
  65. preorderTraversalRealize(node,list);
  66. @SuppressWarnings("unchecked")
  67. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  68. return list.toArray(e);
  69. }
  70. /**
  71. * 前序遍历输出实现
  72. *
  73. * @param node
  74. */
  75. private void preorderTraversalRealize(Node<E> node,List<E> list) {
  76. if (node != null) {
  77. list.add(node.date);
  78. preorderTraversalRealize(node.left,list);
  79. preorderTraversalRealize(node.right,list);
  80. }
  81. }
  82. /**
  83. * 前序遍历输出数组(非递归实现)
  84. *
  85. * @return E[]
  86. */
  87. public E[] preorderTraversalNoRecursion(Node<E> node) {
  88. if(node == null)
  89. return null;
  90. @SuppressWarnings("unchecked")
  91. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  92. Stack<Node<E>> stack = new Stack<Node<E>>();
  93. List<E> list = new ArrayList<E>();
  94. stack.push(node);
  95. while(!stack.empty()){
  96. node = stack.pop();
  97. list.add(node.date);
  98. if(node.right != null){
  99. stack.push(node.right);
  100. }
  101. if(node.left != null){
  102. stack.push(node.left);
  103. }
  104. }
  105. return list.toArray(e);
  106. }
  107. /**
  108. * 中序遍历输出数组
  109. *
  110. * @return E[]
  111. */
  112. public E[] inorderTraversal(Node<E> node) {
  113. List<E> list = new ArrayList<E>();
  114. inorderTraversalRealize(node,list);
  115. @SuppressWarnings("unchecked")
  116. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  117. return list.toArray(e);
  118. }
  119. /**
  120. * 中序遍历输出实现
  121. *
  122. * @param node
  123. */
  124. private void inorderTraversalRealize(Node<E> node,List<E> list) {
  125. if (node != null) {
  126. inorderTraversalRealize(node.left,list);
  127. list.add(node.date);
  128. inorderTraversalRealize(node.right,list);
  129. }
  130. }
  131. /**
  132. * 中序遍历输出,非递归实现
  133. * @return
  134. */
  135. public E[] inorderTraversalNoRecursion(Node<E> node){
  136. if(node == null)
  137. return null;
  138. @SuppressWarnings("unchecked")
  139. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  140. Stack<Node<E>> stack = new Stack<Node<E>>();
  141. List<E> list = new ArrayList<E>();
  142. while(node != null || !stack.empty()){
  143. //存在左子树时
  144. while(node != null){
  145. stack.push(node);
  146. node = node.left;
  147. }
  148. //栈非空时
  149. if(!stack.empty()){
  150. node = stack.pop();
  151. list.add(node.date);
  152. node = node.right;
  153. }
  154. }
  155. return list.toArray(e);
  156. }
  157. /**
  158. * 后序遍历输出数组
  159. *
  160. * @return E[]
  161. */
  162. public E[] postorderTraversal(Node<E> node) {
  163. List<E> list = new ArrayList<E>();
  164. postorderTraversalRealize(node,list);
  165. @SuppressWarnings("unchecked")
  166. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  167. return list.toArray(e);
  168. }
  169. /**
  170. * 后序遍历输出实现
  171. *
  172. * @param node
  173. */
  174. private void postorderTraversalRealize(Node<E> node,List<E> list) {
  175. if (node != null) {
  176. postorderTraversalRealize(node.left,list);
  177. postorderTraversalRealize(node.right,list);
  178. list.add(node.date);
  179. }
  180. }
  181. /**
  182. * 后续遍历(非递归输出)
  183. * @param node
  184. * @return
  185. */
  186. public E[] postorderTraversalNoRecursion(Node<E> node){
  187. if(node == null)
  188. return null;
  189. @SuppressWarnings("unchecked")
  190. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  191. Stack<Node<E>> stack = new Stack<Node<E>>();
  192. List<E> list = new ArrayList<E>();
  193. Node<E> prv = node; //记录之前遍历的右结点
  194. while(node != null || !stack.empty()){
  195. //存在左子树时
  196. while(node != null){
  197. stack.push(node);
  198. node = node.left;
  199. }
  200. //栈非空时
  201. if(!stack.empty()){
  202. Node<E> nodeRight = stack.peek().right;
  203. /*如果右结点为空,或者右结点之前遍历过,获取根结点数据*/
  204. if(nodeRight == null || nodeRight == prv ){
  205. node = stack.pop();
  206. list.add(node.date);
  207. prv = node;
  208. node = null;
  209. }else{
  210. node = nodeRight;
  211. }
  212. }
  213. }
  214. return list.toArray(e);
  215. }
  216. /**
  217. * 广度优先搜索(分层遍历二叉树): 使用队列实现。队列初始化,将根节点压入队列。当队列不为空,
  218. * 进行如下操作:弹出一个节点,访问,若左子节点或右子节点不为空,将其压入队列。
  219. *
  220. * @param node
  221. * @return
  222. */
  223. public E[] layerTraversing(Node<E> node) {
  224. List<E> list = new ArrayList<E>();
  225. layerTraversingRealize(node, list);
  226. @SuppressWarnings("unchecked")
  227. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  228. return list.toArray(e);
  229. }
  230. /**
  231. * 分层遍历辅助函数
  232. * @param node
  233. * @param list
  234. */
  235. private void layerTraversingRealize(Node<E> node, List<E> list) {
  236. Queue<Node<E>> queue = new Queue<Node<E>>();
  237. queue.add(node);
  238. while (!queue.empty()) {
  239. Node<E> n = queue.poll();
  240. list.add(n.date);
  241. if (n.left != null) {
  242. queue.add(n.left);
  243. }
  244. if (n.right != null) {
  245. queue.add(n.right);
  246. }
  247. }
  248. }
  249. /**
  250. * 使用深度优先搜索遍历二叉树,这个结果和前序遍历是一样的
  251. *
  252. * @param node
  253. * @return
  254. */
  255. public E[] depthTraversing(Node<E> node) {
  256. List<E> list = new ArrayList<E>();
  257. depthTraversingRealize(node, list);
  258. @SuppressWarnings("unchecked")
  259. E[] e = (E[])Array.newInstance(node.date.getClass(), 0);//使用泛型数组进行记录
  260. return list.toArray(e);
  261. }
  262. private void depthTraversingRealize(Node<E> node, List<E> list) {
  263. if (node != null) {
  264. list.add(node.date);
  265. depthTraversingRealize(node.left, list);
  266. depthTraversingRealize(node.right, list);
  267. }
  268. }
  269. /**
  270. * 计算二叉树节点的个数
  271. *
  272. * @param node
  273. * @return 二叉树节点的个数
  274. */
  275. public int getNodeNumber(Node<E> node) {
  276. if (node == null) {
  277. return 0;
  278. }
  279. return getNodeNumber(node.left) + getNodeNumber(node.right) + 1;
  280. }
  281. /**
  282. * 求二叉树深度
  283. *
  284. * @return 二叉树深度
  285. */
  286. public int getDepth(Node<E> node) {
  287. if (node == null) {
  288. return 0;
  289. }
  290. int leftDepth = getDepth(node.left);
  291. int rightDepth = getDepth(node.right);
  292. return leftDepth > rightDepth ? leftDepth + 1 : rightDepth + 1;
  293. }
  294. /**
  295. * 求二叉树第K层的节点个数 递归解法: (1)如果二叉树为空或者k<1返回0 (2)如果二叉树不为空并且k==1,返回1
  296. * (3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和
  297. *
  298. * @param k
  299. * @return 二叉树第K层的节点个数
  300. */
  301. public int getNodeNumberInLay(Node<E> node, int k) {
  302. if (node == null || k < 1) {
  303. return 0;
  304. }
  305. if (k == 1) {
  306. return 1;
  307. }
  308. int leftNodeNum = getNodeNumberInLay(node.left, k - 1);
  309. int rightNodeNum = getNodeNumberInLay(node.right, k - 1);
  310. return leftNodeNum + rightNodeNum;
  311. }
  312. /**
  313. * 求二叉树中叶子节点的个数
  314. *
  315. * @param node
  316. * @return
  317. */
  318. public int getNodeNumberLeaf(Node<E> node) {
  319. if (node == null) {
  320. return 0;
  321. }
  322. if (node.left == null && node.right == null) {
  323. return 1;
  324. }
  325. int leftNodeNum = getNodeNumberLeaf(node.left);
  326. int rightNodeNum = getNodeNumberLeaf(node.right);
  327. return leftNodeNum + rightNodeNum;
  328. }
  329. /**
  330. * 判断两棵二叉树是否结构相同 不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。 递归解法: (1)如果两棵二叉树都为空,返回真
  331. * (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假
  332. *
  333. * @param node1
  334. * @param node2
  335. * @return
  336. */
  337. public boolean isStructureCmp(Node<E> node1, Node<E> node2) {
  338. if (node1 == null && node2 == null) {
  339. return true;
  340. } else if (node1 == null || node2 == null) {
  341. return false;
  342. } else {
  343. boolean leftCmp = isStructureCmp(node1.left, node2.left);
  344. boolean rightCmp = isStructureCmp(node1.right, node2.right);
  345. return leftCmp && rightCmp;
  346. }
  347. }
  348. /**
  349. * 判断是否是平衡二叉树
  350. *
  351. * @param node
  352. * @return
  353. */
  354. public boolean isAVL(Node<E> node) {
  355. if (node == null) {
  356. return true;
  357. }
  358. int leftHeight = getDepth(node.left);
  359. int rightHeight = getDepth(node.right);
  360. if (Math.abs(leftHeight - rightHeight) > 1) {
  361. return false;
  362. } else {
  363. return isAVL(node.left) && isAVL(node.right);
  364. }
  365. }
  366. /**
  367. * 判断是否完全二叉树 1.当发现有一个节点的左子树为空,右子树不为空时 直接返回false.
  368. * 2.当发现有一个节点的左子树不为空,右子树为空时,置标志位为1。 3.当发现有一个节点的左右子树均为空时,置标志位为1。
  369. *
  370. * @param node
  371. * @return
  372. */
  373. public boolean isCompleteBinaryTree(Node<E> node) {
  374. if (node == null) {
  375. return true;
  376. }
  377. Queue<Node<E>> queue = new Queue<Node<E>>();
  378. queue.add(node);
  379. int flag = 0;// 标记此节点以下的节点均应为叶子节点(没有左右孩子),否则此树为一棵非完全二叉树。
  380. while (!queue.empty()) {
  381. Node<E> n = queue.poll();
  382. if (n.left != null) {
  383. if (flag == 1) {
  384. return false;
  385. }
  386. queue.add(n.left);
  387. if (n.right != null) {
  388. queue.add(n.right);
  389. } else {
  390. flag = 1;
  391. }
  392. } else {
  393. if (n.right != null) {
  394. return false;
  395. }
  396. flag = 1;
  397. }
  398. }
  399. return true;
  400. }
  401. /**
  402. * 根据前序遍历结果和中序遍历结果重建二叉树
  403. *
  404. * @param preorderTraversalArray
  405. * 前序遍历结果
  406. * @param inorderTraversalArray
  407. * 中序便利结果
  408. * @return 二叉树
  409. */
  410. public BinaryTree<E> reBuildBinaryTree(E[] preorderTraversalArray, E[] inorderTraversalArray) {
  411. if (preorderTraversalArray == null || inorderTraversalArray == null) {
  412. return null;
  413. }
  414. Node<E> root = reBuildBinaryTreeRealize(preorderTraversalArray, 0, preorderTraversalArray.length - 1,
  415. inorderTraversalArray, 0, inorderTraversalArray.length - 1);
  416. BinaryTree<E> bt = new BinaryTree<E>();
  417. bt.rootNode = root;
  418. bt.depth = getDepth(root);
  419. return bt;
  420. }
  421. /**
  422. * 前序遍历的第一个节点一定是二叉树的根节点(以a记录),中序遍历以a为分界线,a左边的一定是左子树一边的(记录下左边的个数为x),且为左子树的中序遍历结果,
  423. * a右边的一定是右子树一边的(记录下右边的个数为y),且为右子树中序遍历的结果。再把前序遍历结果a后面x个数作为左子树的前序遍历,剩下的y个作为右子树的前序遍历,
  424. * 再一次进行递归建立,直到完全建立二叉树
  425. *
  426. * @param preOrder 前序遍历
  427. * @param startPreIndex 前序遍历起始位置
  428. * @param endPreIndex 前序遍历结束为止
  429. * @param inOrder 后序遍历
  430. * @param startInIndex 后续遍历起始位置
  431. * @param endInIndex 后序遍历结束位置
  432. * @return
  433. */
  434. public Node<E> reBuildBinaryTreeRealize(E[] preOrder, int startPreIndex, int endPreIndex, E[] inOrder,
  435. int startInIndex, int endInIndex) {
  436. Node<E> root = new Node<E>(preOrder[startPreIndex]);
  437. // 只有一个元素
  438. if (startPreIndex == endPreIndex) {
  439. if (startInIndex == endInIndex && preOrder[startPreIndex] == inOrder[startInIndex]) {
  440. return root;
  441. } else {
  442. throw new RuntimeException("出错");
  443. }
  444. }
  445. // 在中序遍历中找到根结点的索引
  446. int rootInIndex = startInIndex;
  447. while (rootInIndex <= endInIndex && inOrder[rootInIndex] != preOrder[startPreIndex]) {
  448. ++rootInIndex;
  449. }
  450. if (rootInIndex == endInIndex && inOrder[rootInIndex] != preOrder[startPreIndex]) {
  451. throw new RuntimeException("出错");
  452. }
  453. int leftLength = rootInIndex - startInIndex;
  454. int leftPreOrderEndIndex = startPreIndex + leftLength;
  455. if (leftLength > 0) {
  456. // 构建左子树
  457. root.left = reBuildBinaryTreeRealize(preOrder, startPreIndex + 1, leftPreOrderEndIndex, inOrder, startInIndex,
  458. rootInIndex - 1);
  459. }
  460. if (leftLength < endPreIndex - startPreIndex) {
  461. // 右子树有元素,构建右子树
  462. root.right = reBuildBinaryTreeRealize(preOrder, leftPreOrderEndIndex + 1, endPreIndex, inOrder, rootInIndex + 1,
  463. endInIndex);
  464. }
  465. return root;
  466. }
  467. }

二、排序

  1. package com.cn;
  2. import java.util.Arrays;
  3. /**
  4. * 经典排序复习
  5. * @author lvbiao
  6. *
  7. */
  8. public class Sort {
  9. /**
  10. * 交换数组中两个指定位置的数据
  11. * @param array
  12. * @param i
  13. * @param j
  14. */
  15. private void swap(int[] array, int i, int j) {
  16. int var;
  17. var = array[i];
  18. array[i] = array[j];
  19. array[j] = var;
  20. }
  21. public void display(int[] array){
  22. System.out.println(Arrays.toString(array));
  23. }
  24. /**
  25. * 冒泡排序
  26. * @param array
  27. */
  28. public void bubbleSort(int[] array){
  29. for(int i = 0; i < array.length; i++){
  30. for(int j = array.length-1; j > i; j--){
  31. if(array[j-1] > array[j]){
  32. swap(array,j-1,j);
  33. }
  34. }
  35. }
  36. }
  37. /**
  38. * 选择排序
  39. * @param array
  40. */
  41. public void selectSort(int[] array){
  42. int min;
  43. for(int i = 0; i < array.length; i++){
  44. min = i;
  45. for(int j = i+1; j < array.length; j++){
  46. if(array[min] > array[j]){
  47. min = j;
  48. }
  49. }
  50. if(min != i){
  51. swap(array, i, min);
  52. }
  53. }
  54. }
  55. /**
  56. * 插入排序
  57. * @param array
  58. */
  59. public void insertSort(int[] array){
  60. int j;
  61. for(int i = 1; i < array.length; i ++){
  62. if(array[i] < array[i-1]){
  63. int var = array[i];
  64. j = i - 1;
  65. while(j >= 0 && var < array[j]){
  66. array[j+1] = array[j];
  67. j--;
  68. }
  69. array[j+1] = var;
  70. }
  71. }
  72. }
  73. /**
  74. * 希尔排序
  75. * @param array
  76. */
  77. public void shellSort(int[] array){
  78. int length = array.length;
  79. int j;
  80. do{
  81. length = length/3 + 1;
  82. for(int i = length; i < array.length; i ++){
  83. if(array[i] < array[i-length]){
  84. int var = array[i];
  85. j = i -length;
  86. while(j >= 0 && var < array[j]){
  87. array[j+length] = array[j];
  88. j-=length;
  89. }
  90. array[j+length] = var;
  91. }
  92. }
  93. }while(length > 1);
  94. }
  95. /**
  96. * 推排序
  97. * @param array
  98. */
  99. public void headSort(int[] array){
  100. //将整个数组构建成一个大顶堆
  101. for(int i = (array.length-1)/2; i >= 0; i--){
  102. headBig(array,i,array.length-1);
  103. }
  104. //将大顶堆树根上的数据与数组末尾的交换,再将数组除开最后一个再构成一个大顶堆,一次循环知道完成排序
  105. for(int i = array.length-1; i > 0; i--){
  106. swap(array,0,i);
  107. headBig(array,0,i-1);
  108. }
  109. }
  110. /**
  111. * 将array调整为一个大顶堆
  112. * @param array
  113. * @param i
  114. * @param j
  115. */
  116. private void headBig(int[] array, int start, int stop) {
  117. int i;
  118. int var = array[start];
  119. for(i = 2*start; i <= stop; i*=2){
  120. if(i+1 >= array.length){
  121. if(array[i/2] < array[i]){
  122. array[i/2] = array[i];
  123. start = i;
  124. break;
  125. }else{
  126. break;
  127. }
  128. }
  129. if(array[i] < array[i+1] && i < stop){
  130. ++i;
  131. }
  132. if(var >= array[i]){
  133. break;
  134. }
  135. array[start] = array[i];
  136. start = i;
  137. }
  138. array[start] = var;
  139. }
  140. /**
  141. * 归并排序
  142. * @param array
  143. */
  144. public void mergeSort(int[] array){
  145. int[] temp = new int[array.length];
  146. mSort(array, temp, 0, array.length-1);
  147. }
  148. //msort函数是将list数组进行分割,merge函数是将分割后的list数组进行排序在组合
  149. private void mSort(int[] list, int[] temp, int left, int right){
  150. if(left == right){
  151. return;
  152. }else{
  153. int mid = (left + right) / 2;
  154. mSort(list,temp,left,mid);
  155. mSort(list,temp,mid+1,right);
  156. merge(list,temp,left,mid+1,right);
  157. }
  158. }
  159. private void merge(int[] list,int[] temp,int left,int mid,int right){
  160. int j = 0;
  161. int leftTemp = left;
  162. int midTemp = mid - 1;
  163. int n = right - left + 1; //当前temp数组中数的个数
  164. //左右数组第一个数进行比较 把较小的数如到temp数组中
  165. while(left <= midTemp && mid <= right){
  166. if(list[left] < list[mid]){
  167. temp[j++] = list[left++];
  168. }else{
  169. temp[j++] = list[mid++];
  170. }
  171. }
  172. //如果左边的数比右边的数多,就将剩下的入到temp数组中 j
  173. while(left <= midTemp){
  174. temp[j++] = list[left++];
  175. }
  176. //如果右边打数比左边的数多,就将右边剩下的数加入到temp数组当中去
  177. while(mid <= right){
  178. temp[j++] = list[mid++];
  179. }
  180. //将得到的temp数组加到list数组中
  181. for(j = 0; j < n; j++){
  182. list[leftTemp+j] = temp[j];
  183. }
  184. }
  185. /**
  186. * 快速排序
  187. * @param array
  188. */
  189. public void quickSort(int[] array){
  190. qSort(array, 0, array.length-1);
  191. }
  192. private void qSort(int[] array, int left, int right) {
  193. if(left < right){
  194. int mid = partition(array, left, right);
  195. qSort(array, left, mid-1);
  196. qSort(array, mid+1, right);
  197. }
  198. }
  199. //返回一个关键字,使得这个关键字左边的数都比他小,右边的数都比它大
  200. private int partition(int[] array, int left, int right) {
  201. int result = array[left];
  202. while(left < right){
  203. while(left < right && array[right] >= result){
  204. right--;
  205. }
  206. swap(array, left, right);
  207. while(left < right && array[left] <= result){
  208. left++;
  209. }
  210. swap(array, left, right);
  211. }
  212. array[left] = result;
  213. return left;
  214. }
  215. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注