(완전 이진 트리에 한정되지 않음) 노드 이진 층 분석 - 진 트리 데이터 구조 []

만든 사람 : 2019년 5월 23일 - 5.25

 

개별 사고 과정의 광범위한 사용하지 않는 쉬운 방법.

 

이진 트리 분석 다수의 층의 접속점 (균형 이진 트리에 한정되는 것은 아니다) :

 

BinaryNode <T> P;

 

완전한 바이너리 트리는 식에 따라 노드 P의 층의 수를 산출 할 수있다

노드 P 노드 i 번째 인 경우 (I> = 0), +1은 층의 수로부터 계산 될 수 H = (LOG2의 I)의 특성에 따라 완전한 바이너리 트리

 

이진 트리의 공통 노드는, 알고리즘 등 어떤 공식이 존재하지 않는 경우는 층의 수를 계산하려면 :

 

  •   생각 :
  1. 리스트 탐색을 사용하여 생성 된 레이어

결과 : 각 노드가 유일한 시리얼 번호를 그릴은 층의 수를 판단 할 수 없다

 

  •  (타당) 당사국 : 프리앰블 시퀀스 preList를 사용하여 빈 트리를 표시

층 int 배열을 정의

각각이 식별자가 널 (null), 소자 층의 값이면, 두 식별 비어 +1 레벨을 통과 뒤로 탐색 (빈 식별 포함) 소자 현명한 값 -1 층 세 빈 식별 시 층 값 -3

 

(가능) 예 A :

prelist = (A ^ B의 D G ^ ^^ C E F ^^ ^^)

레벨 [] = 1 2 3 4 4 5 5 5 1 2 3 4 4 3 4 4

 

 

 

(유력한) 실시 예 II :

Prelist = (A ^ B에 E F ^^ C ^ D G ^^)

레벨 [] = (1, 2, 3, 4, 4, 5, 5,  4 ,   5, 5, 6, 7, 7, 7, 4)

                                                   

 

 

  •   (개) 방법 2 : 사용 빈 트리 식별 프리앰블 시퀀스 preList 표시 levelList 얻어진 레벨을 횡단

 

* ArrayList를 가진 제네릭 대신 배열의

배열 번호 정의 스토리지 계층 구조, 길이는 이진 트리 노드의 수

메인 이송 leveList , 실시 예에 나타낸 방법

 

 

(가능) 예 A :

prelist = (A ^ B의 D C E G ^^^ ^^ F ^^)

levelList = (A B C D E F G)

레벨 [] = 1 2 2 3 3 3 4

 

 

 

프로세스 :

단지 루트 노드, 상기 제 1 층수 확실히 1

두 번째 B- 층 (2)는 확실히 ;

LevelList 인덱스 점 C , preList의 첨자 가리 D , 동일하지 않은 경우, 층의 수가 동일하고 preList의 변경 첨자;

* 이유 :

levelist B의는 다음으로 C 또는 C는 B의 인 어린이, 또는 C가 B입니다 형제. preList에서 , B는 (C는 다음 요소는 C되지 B하지 의 아이들) , 그래서 C는 B 확실히 형제

 

LevelList 인덱스 점 D , preList의 인덱스이며 여전히 D 층 + 1의 개수와 동일, (D의 층이다. 3 ) preList의 첨자 + 1 (지점 G )

* 이유 : D C에서이 뒤에, D는 A B의 수 있습니다 아이도 C에있을 수 있습니다 아이,하지만 중요한, 확실히 형제가 아닌 아이, 레이어 1의 수 (이것은 이진 트리이기 때문에)

 

(가능) 예 II :

Prelist = (A ^ B에 E F ^ C ^ D G ^ ^ ^)

levelList = (A B D E F G C)

레벨 [] = (1, 2, 3, 3, 4, 4, 4)

 

 

(개선 가능) 실시 예 방법 3 :

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)

레벨 [] = (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     }

 

추천

출처www.cnblogs.com/musecho/p/11201074.html