Created: 2019.5.23 - 5.25
Individual thought process, not an easy way to widespread use of.
Analyzing binary tree (balanced binary tree is not limited to) the junction point of a number of layers:
BinaryNode<T> p;
Complete binary tree may be calculated according to the formula the number of layers of the node p
If the node p is the i th node (i> = 0), the complete binary tree in accordance with the nature of h = (log2 i) +1 can be calculated from the number of layers
To calculate the number of layers if a common node of the binary tree, there is no formula, like the algorithm:
- Thinking:
- The resulting layers using the list traversal
Results: The only draw serial number of each node, the number of layers can not be determined
- (Feasible) a Party: marked empty tree using the preamble sequence preList
Define an int array of layers
The element-wise (including empty identification) back traversal, each traversing a +1 level, when the identifier is a null, the value of the element layer, the two identification is empty, the value -1 layer, three empty identification when the layer value -3
(Possible) Example a:
prelist= (A B D ^ G ^ ^ ^ C E ^ ^ F ^ ^)
level[]= 1 2 3 4 4 5 5 5 2 3 4 4 3 4 4
(Viable) Example II:
Prelist= ( A B E ^ F ^ ^ C ^ D G ^ ^ ^ ^ )
Level[]= (1, 2 , 3, 4, 4 , 5, 5, 4, 5, 5, 6, 7 , 7, 7 ,4 )
3
- (Improved) Method 2: Using marked empty tree identification preamble sequence preList levelList and traverse the level obtained
* Generics with ArrayList instead of Array
A storage hierarchy defined array number, length is the number of binary tree nodes
The main traverse leveList , a process shown in Example
(Possible) Example a:
prelist= ( A B D ^ G ^^^C E ^^ F ^^)
levelList= (A B C D E F G )
level[]= 1 2 2 3 3 3 4
process:
Only a root node, so the first A number of layers is certainly 1
The second B- layers 2 is certainly ;
LevelList index point C , preList subscripts point D , if not equal, the same number of layers, and preList subscript unchanged;
* Why:
levelist in B next is C or C is B children, or C is B Brothers. In preList , B is the next element is not C (C is not B 's children) , so C is definitely B Brothers
LevelList index point D , preList index is still D , equal to the number of layers + 1 (D layers is. 3 ), preList subscript + 1 (point G )
* Why: D in C behind, D may be a B child may also be C child, but a child who is not important, certainly not brothers (because it is a binary tree), the number of layers +1
(Possible) Example II:
Prelist= ( A B E ^ F ^^ C ^ D G ^ ^^ ^)
levelList= (A B E C F D G )
level[]= ( 1, 2, 3, 3, 4, 4, 4 )
(The improved feasible) Example Three:
Prelist = (100, 40, 19, ^^, 21, ^^, 60, 28, 11, 5, 2, ^^, 3, ^^, 6, 17, 7, ^^, 10, ^^, 32 , ^^)
levelList= (100, 40, 60, 19, 21, 28, 32, 11, 17 , 5, 6, 7, 10, 2, 3 )
level[]= ( 1, 2, 2, 3, 4, 4, 4, 4 , 4, 4, 4, 4, 4, 4, 4 )
3 3 3 4 4 5 5 5 5 6 6
改进1:(加条件)若prelist中遍历到的元素前有连续两个空标识,层数也不变(不论元素是否相等),preList下标+1
改进2:若在preList中遍历到levelList指向元素之前遍历过的元素,直接该元素
(不可以只是跳过,因为还要判断preFlag指向前两个元素是否为空标识^)
过程:
(部分)
LevelList中指标指向21,Prelist指向21,相等,但因为prelist的21前有两个连续空标识,所以层数不变;
*为什么:
LevelList中21在19的后面,21可能是19的孩子,21也可能是19的兄弟,看preList,虽然指向21,但前有两个空标识,说明21肯定不是19的孩子(两个孩子位被空标识占去),21只可能是19的兄弟,所以层数不变。
LevelList中指标指向28,Prelist指向60,因为levelList中60在28之前已经出现过,所以跳过这个元素,preflag++
*为什么:
判断一个元素的层数只需要知道,它与前面一个结点的关系(孩子还是兄弟),无需知道更前面哪些元素的信息。由于这个前面出现过的元素的层数已经计算得出,可以直接删去该元素。
例四:
preList= (18,7, ^^ , 11, 5, ^^, 6, 2,^^, 4,^^)
levelList= (18, 7, 11, 5, 6, 2, 4 )
Level[]= ( 1, 2, 2, 3, 3, 4, 4 )
算法实现代码:(已测试)
1 /** 2 * @title: nodelevel 3 * @description: get a given node's level 4 * @author: Navis 5 * @date: May 25, 2019 6:04:49 PM 6 * @param p as root node 7 * @return int :level 8 * @throws:IllegalArgumentException:p==null 9 */ 10 public int nodelevel(BinaryNode<T> p) { 11 if (this.root == null) 12 return -1; 13 if (p == null) 14 throw new IllegalArgumentException("p==null"); 15 16 int nodeCount = this.getNodeConut(); 17 int[] lev = new int[nodeCount]; 18 19 ArrayList preList = this.getPrelist(this.root); 20 ArrayList levelList = this.levelList(); 21 int nodeNum = levelList.indexOf(p.data); // p在levelList中的元素位置 22 23 lev[0] = 1;// 根结点只有一个,所以第一个元素层数是1 24 lev[1] = 2;// 第二个元素的层数是2; 25 26 int preFlag = 2; 27 Object firstBefore = preList.get(0); 28 Object secondBefore = preList.get(1); 29 // 计算层数数组lev[] 30 for (int i = 2; i < levelList.size(); i++) {// 从第3个元素开始 31 for (int k = 0; k < i; k++) {// 若preFlag指向元素,在levelList的第i个元素前已经出现过,则删除该元素 32 if (preList.get(preFlag).equals(levelList.get(k))) { 33 preList.remove(preFlag); 34 35 k = 0;// k重新开始循环,判断更新后的preFlag位置元素是否之前出现过 36 } 37 } 38 if (firstBefore.equals("^") && secondBefore.equals("^")) { 39 lev[i] = lev[i - 1]; 40 41 preFlag++; 42 while (preList.get(preFlag).equals("^")) { 43 preFlag++; 44 } 45 firstBefore = preList.get(preFlag - 1);// preFlag指向元素的前面第一个元素 46 secondBefore = preList.get(preFlag - 2);// preFlag指向元素的前面第二个元素 47 } else { 48 if (preList.get(preFlag).equals(levelList.get(i))) {// 相等 49 lev[i] = lev[i - 1] + 1; 50 51 preFlag++; 52 while (preList.get(preFlag).equals("^")) {// 跳过^空标识,指向有值元素 53 preFlag++; 54 if (preFlag >= preList.size()) {// 防止preList后面全是^空标识,导致一直循环下去 55 break; 56 } 57 } 58 firstBefore = preList.get(preFlag - 1); 59 secondBefore = preList.get(preFlag - 2); 60 } else {// 不相等 61 lev[i] = lev[i - 1]; 62 } 63 } 64 // System.out.println(levelList.get(i) + ":" + lev[i]); 65 } 66 return lev[nodeNum]; 67 } 68 69 70 /** 71 * @title: getNodeConut 72 * @description: getNodeCount 73 * @author: Navis 74 * @date: May 24, 2019 10:55:13 AM 75 * @return int nodeCount 76 */ 77 public int getNodeConut() { 78 int nodeCount = 0; 79 ArrayList prelist = this.getPrelist(this.root);// 得到带有空子树标识的prelist 80 81 for (int i = 0; i < prelist.size(); i++) { 82 if (prelist.get(i) != "^") 83 nodeCount++; 84 } 85 86 return nodeCount; 87 } 88 89 /** 90 * @title: getPrelist 91 * @description: getPrelist; with emptySubTree sign 92 * @author: Navis 93 * @date: May 24, 2019 10:30:34 AM 94 * @param BinaryNode<T> p 95 * @return ArrayList prelist 96 */ 97 public ArrayList getPrelist(BinaryNode<T> p) { 98 ArrayList prelist = new ArrayList(); 99 preorder(prelist, p); 100 101 return prelist; 102 } 103 104 /** 105 * @title: levelList 106 * @description: get levelList;levelOrder 107 * @author: Navis 108 * @date: May 24, 2019 11:54:07 AM 109 * @return ArrayList levelList 110 */ 111 public ArrayList levelList() { 112 LinkedQueue<BinaryNode<T>> queue = new LinkedQueue<>();// 空队列 113 BinaryNode<T> p = this.root;// 根结点不入队 114 ArrayList levelList = new ArrayList(); 115 116 while (p != null) { 117 levelList.add(p.data); // 将已出队结点p的元素值加入levelList 118 119 if (p.left != null) 120 queue.add(p.left);// p的左孩子入队 121 if (p.right != null) 122 queue.add(p.right);// p的右孩子入队 123 124 p = queue.poll();// p指向出队结点,若队列为空返回null 125 } 126 return levelList; 127 }