이 진 트 리 의 각종 조작 총화
모든 원본 코드:https://github.com/qzxin/BinaryTree/blob/master/binary-tree-all.cpp
1. 이 진 트 리 의 노드 갯 수 구하 기
재 귀 구 해, 이 진 트 리 의 노드 개 수 는 왼쪽 서브 트 리 의 개수 + 오른쪽 서브 트 리 의 개수 + 1 (뿌리) 과 같 습 니 다.
//          
int GetNums(BinaryTreeNode* root) {
    if (root == NULL)
        return 0;
    return GetNums(root->m_pLeft) + GetNums(root->m_pRight) + 1;
}이 진 트 리 의 잎 노드 의 개 수 를 구하 다.
잎 노드 의 정 의 는 자신 이 비어 있 지 않 고 좌우 가 NULL 입 니 다.이 진 트 리 의 노드 개 수 를 구 하 는 것 과 유사 합 니 다. 좌우 가 NULL 이 어야 만 1 개 입 니 다.
int GetLeafNodeNums(BinaryTreeNode* root) {
    if (root == NULL)
        return 0;
    if (root->m_pLeft == NULL && root->m_pRight == NULL)
        return 1;
    int leftNums = GetLeafNodeNums(root->m_pLeft);
    int rightNums = GetLeafNodeNums(root->m_pRight);
    return leftNums+rightNums;
}2. 이 진 트 리 깊이 구하 기
재 귀 구 해, 이 진 트 리 의 깊이 는 좌우 서브 트 리 깊이 의 최대 치 + 1 (뿌리) 과 같 습 니 다.
//        
int GetDepth(BinaryTreeNode* root) {
    if (root == NULL)
        return 0;
    return max(GetDepth(root->m_pLeft), GetDepth(root->m_pRight)) + 1;
}3. 이 진 트 리 K 층 노드 개수 구하 기
귀속 실현 k = 1, nums = 1;이 진 트 리 K 층 의 노드 개수 = 왼쪽 트 리 K - 1 층 의 노드 개수 + 오른쪽 트 리 K - 1 층 의 노드 개수
//      K      
int GetNLevelNums(BinaryTreeNode* root, int k) {
    if (root == NULL || k == 0)
        return 0;
    if (k == 1)
        return 1;
    //     k-1      
    return GetNLevelNums(root->m_pLeft, k-1) + GetNLevelNums(root->m_pRight, k-1);
}4. 재 귀적: 앞 순서, 가운데 순서, 뒤 순서
//     :    ,    ,    
void visit(BinaryTreeNode* root) {
    cout << root->m_val << " ";
}
void PreOrderTravel(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    visit(root);
    PreOrderTravel(root->m_pLeft);
    PreOrderTravel(root->m_pRight);
}
void InOrderTravel(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    InOrderTravel(root->m_pLeft);
    visit(root);
    InOrderTravel(root->m_pRight);
}
void PostOrderTravel(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    PostOrderTravel(root->m_pLeft);
    PostOrderTravel(root->m_pRight);
    visit(root);
}5. 비 재 귀적 옮 겨 다 니 기: 앞 순서, 중간 순서, 뒤 순서, 층 순서
5.1 앞 순서 옮 겨 다 니 기
먼저 뿌리 에 접근 한 다음 에 오른쪽 노드 를 누 르 고 왼쪽 노드 는 창고 에 들어간다.(방문 시 순 서 는 뿌리, 왼쪽, 오른쪽)
void PreOrderTravel(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    stack5. 2 중 순 옮 겨 다 니 기
먼저 창고 에 들 어간 후에 방문 하 다.중간 순 서 는 먼저 왼쪽 노드 를 방문 해 야 하기 때문에 나무의 마지막 왼쪽 노드 를 눌 러 야 접근 할 수 있 습 니 다.마지막 왼쪽 노드 에 왼쪽 노드 (뿌리 에 해당) 가 없 으 면 오른쪽 트 리 를 옮 겨 다 니 기 시작 합 니 다.
void InOrderTravelRecur(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    stack5.3 후 순 옮 겨 다 니 기
2 개의 창고 로 실현,
//    s1:  ,  ,  ; 
//  s2:     ,  ,  ;(      : , , )
void PostOrderTravelRecur(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    stack5.4 층 차 옮 겨 다 니 기
한 층 한 층 방문, 먼저 들 어가 고 먼저 나 가 며 대기 열 을 사용 하여 이 루어 집 니 다.루트 에 접근 한 후 왼쪽, 오른쪽으로 대기 열 에 들 어 갑 니 다.
void LevelOrderTravel(BinaryTreeNode* root) {
    if (root == NULL)
        return;
    queue6. 이 진 트 리 를 질서 있 는 양 방향 링크 로 바 꿉 니 다.
순환 실현, 이 진 트 리 는 왼쪽 나무, 뿌리, 오른쪽 나무 로 나 눌 수 있 습 니 다. 양 방향 링크 의 머리 끝 은 pFirst, pLast 입 니 다.
따라서 최종 양 방향 링크 의 머리 와 꼬리 를 밝 히 는 것 외 에 왼쪽, 오른쪽 트 리 가 양 방향 링크 의 머리 와 꼬리 로 바 뀌 었 다 고 밝 혔 다.
//                
void CovertToList(BinaryTreeNode* root, BinaryTreeNode* &pFirst, BinaryTreeNode* &pLast) {
    BinaryTreeNode* pLeftFirst(NULL), *pLeftLast(NULL), *pRightFirst(NULL), *pRightLast(NULL);
    if (root == NULL) {
        pFirst = NULL;
        pLast = NULL;
        return;
    }
    if (root->m_pLeft == NULL) {
        pFirst = root;
    } else {
        CovertToList(root->m_pLeft, pLeftFirst, pLeftLast);
        pLeftLast->m_pRight = root; 
        root->m_pLeft = pLeftLast;
        pFirst = pLeftFirst;
    }
    if (root->m_pRight == NULL) {
        pLast = root;
    } else {
        CovertToList(root->m_pRight, pRightFirst, pRightLast);
        pRightFirst->m_pLeft = root;
        root->m_pRight = pRightFirst;
        pLast = pRightFirst;
    }
}7. 이 진 트 리 의 거울 을 구하 라
재 귀 하 는 교환 나무의 좌우 나무.
//        
BinaryTreeNode* MirrorTree(BinaryTreeNode* root) {
    if (root == NULL)
        return NULL;
    BinaryTreeNode* pLeft = MirrorTree(root->m_pLeft);
    BinaryTreeNode* pRight = MirrorTree(root->m_pRight);
    root->m_pLeft = pRight;
    root->m_pRight = pLeft;
    return root;
}8. 이 진 트 리 두 그루 의 구조 가 동일 한 지 판단
재 귀 실현: 먼저 뿌리 가 같은 지 판단 한 다음 에 왼쪽 나무 와 오른쪽 나무 가 같은 지 판단 합 니 다 / / 두 그루 의 이 진 트 리 가 구조 가 같은 지 판단 합 니 다.
bool TreeStructCmp(BinaryTreeNode* root1, BinaryTreeNode* root2) {
    if (root1 == NULL && root2 == NULL)
        return true;
    if (root1 != root2)
        return false;
    bool leftResult = TreeStructCmp(root1->m_pLeft, root2->m_pLeft);
    bool rightResult = TreeStructCmp(root1->m_pRight, root2->m_pRight);
    return leftResult && rightResult;
}9. 이 진 트 리 가 밸 런 스 이 진 트 리 인지 판단
모든 나무 가 균형 트 리 여야 균형 트 리 라 는 것 을 보증 할 수 있다.따라서 좌우 나무 가 균형 이 맞 는 지 판단 하고 좌우 나무의 깊이 를 기록 한 뒤 나무의 균형 여 부 를 판단 한다.
bool IsAVL(BinaryTreeNode* root) {
    int depth;
    return IsAVLTree(root, depth);
}
//     ,   1   
bool IsAVLTree(BinaryTreeNode* root, int &depth) {
    if (root == NULL) {
        depth = 0;
        return true;
    } 
    int leftDepth, rightDepth;
    //     ,             ,        
    if (IsAVLTree(root->m_pLeft, leftDepth) && IsAVLTree(root->m_pRight, rightDepth)) {
        if (abs(leftDepth-rightDepth) <= 1) {
            depth = max(leftDepth, rightDepth)+1;
            return true;
        }
    }
    return false;
}10. 이 진 트 리 가 이 진 트 리 검색 인지 판단
주의: 왼쪽 노드 < = 뿌리 < = 오른쪽 노드 만 비교 하면 이것 은 이 진 트 리 를 검색 하 는 것 이 라 고 판단 할 수 없습니다. 이것 은 오른쪽 트 리 의 모든 노드 값 이 왼쪽 트 리 의 모든 노드 보다 크다 는 것 을 보장 할 수 없 기 때 문 입 니 다.아래 그림 에서 보 듯 이 그것 은 BST 가 아니다.
    4
1       5
     0     6중간 순 서 를 통 해 이 진 트 리 를 검색 하 는 지 여 부 를 판단 합 니 다.
//              
bool IsBST(BinaryTreeNode* root) {
    int prev = INT_MIN; //     ,    
    return IsBSTreeHelper(root, prev);
}
//     ,             
bool IsBSTreeHelper(BinaryTreeNode* root, int &prev) {
    if (root == NULL)
        return true;
    if (IsBSTreeHelper(root->m_pLeft, prev)) {
        if (root->m_val >= prev) {
            prev = root->m_val;
            if (IsBSTreeHelper(root->m_pRight, prev))
                return true; //      、 、        
            else
                return false; //     
        } else {
            return false; //     
        }
    } else {
        return false; //     
    }
}11. 이 진 트 리 가 완전 이 진 트 리 인지 아 닌 지 판단
완전 이 진 트 리 는 마지막 층 오른쪽 에 있어 야 빈 노드 가 존재 할 수 있 습 니 다.한 노드 에 빈 트 리 가 있 으 면 모든 노드 에 NULL 만 포함 되 어야 합 니 다.
/              
//     ,            ,            NULL
bool IsCompleteBinaryTree(BinaryTreeNode* root) {
    if (root == NULL)
        return true;
    queue<BinaryTreeNode* > q;
    bool HaveNULL = false;
    q.push(root);
    while (q.empty() == false) {
        root = q.front();
        q.pop();
        if (HaveNULL) {
            if (root->m_pLeft || root->m_pRight)
                return false;
        } else {
            if (root->m_pLeft && root->m_pRight) {
                //     
                q.push(root->m_pLeft);
                q.push(root->m_pRight);
            } else if (root->m_pLeft && root->m_pRight == NULL) {
                //    ,  
                HaveNULL = true;
                q.push(root->m_pLeft);
            } else if (root->m_pLeft == NULL && root->m_pRight) {
                //   ,   
                return false;
            } else {
                //     
                HaveNULL = true;
            }
        }
    }
    return true;
}12. 이 진 트 리 에서 두 노드 의 최저 공공 조상 노드 를 구한다.
재 귀 해법: (1) 만약 에 두 노드, 하 나 는 왼쪽 나무 에 있 고 하 나 는 오른쪽 나무 에 있 으 면 가장 낮은 공공 조상 노드 는 뿌리 (2) 이다. 만약 에 두 노드 가 모두 왼쪽 나무 에 있 으 면 재 귀 하여 왼쪽 나 무 를 처리한다.반대로 오른쪽 하위 트 리 처리
트 리 에서 node 1 을 찾 고 경 로 를 저장 합 니 다. node 1 을 찾 지 못 하면 경로 의 노드 pop 을 되 돌려 줍 니 다.트 리 에서 node 2 를 찾 고 경 로 를 저장 합 니 다. node 1 을 찾 지 못 하면 경로 의 노드 pop 을 되 돌려 줍 니 다.1 개 를 찾 지 못 하면 NULL 로 돌아 가 고, 다 찾 으 면 2 개의 경 로 를 시작 으로 뒤로 옮 겨 다 니 며 마지막 공 통 된 노드 를 찾 습 니 다.
//                   
BinaryTreeNode* GetLastCommonParent(BinaryTreeNode* root, BinaryTreeNode* node1, BinaryTreeNode* node2) {
    if (root == NULL || node1 == NULL || node2 == NULL)
        return NULL;
    list13. 이 진 트 리 의 노드 최대 거리 구하 기
이 진 트 리 에서 노드 의 최대 거리 max Distance 는 두 노드 가 연 결 된 경로 길이 의 최대 치 를 말 합 니 다.
int GetMaxDistance(BinaryTreeNode* root) {
    int maxLeft = 0, maxRight = 0; //            
    return GetMaxDistRecur(root, maxLeft, maxRight); //         ,             
}
//maxLeft, maxRight                
int GetMaxDistRecur(BinaryTreeNode* root, int &maxLeft, int &maxRight) {
    if (root == NULL) {
        maxLeft = 0, maxRight = 0;
        return 0;
    }
    int maxLL, maxLR, maxRL, maxRR;
    int maxDistLeft, maxDistRight; //  、         
    if (root->m_pLeft) {
        maxDistLeft = GetMaxDistRecur(root->m_pLeft, maxLL, maxLR);
        maxLeft = max(maxLL, maxRR) + 1;
    } else {
        maxDistLeft = 0;
        maxLeft = 0;
    }
    if (root->m_pRight) {
        maxDistRight = GetMaxDistRecur(root->m_pRight, maxRL, maxRR);
        maxRight = max(maxRL, maxRR) + 1;
    } else {
        maxDistRight = 0;
        maxRight = 0;
    }
    return max(maxLeft+maxRight, max(maxDistLeft, maxDistRight));
}
14. 앞 순서 와 중간 순서 로 두 갈래 나 무 를 재 구축 합 니 다.
앞 순 서 는 뿌리 이다.중 서 의 한 노드 의 왼쪽 은 왼쪽 나무 이 고 오른쪽 은 오른쪽 나무 이다.따라서 이전 순서 에서 1 개의 뿌리 를 확정 한 다음 에 중간 순서 에서 이 뿌리 를 찾 아 이 뿌리 에 속 하 는 좌우 나무 범 위 를 확인한다.좌우 자 수 를 재 귀적 으로 처리 하 다.
//                    
BinaryTreeNode* RebuildBinaryTree(int* preorder, int* inorder, int nums) {
    if (preorder == NULL || inorder == NULL || nums <= 0)
        return NULL;
    BinaryTreeNode* root = new BinaryTreeNode(preorder[0]); //  
    int rootPositionOnInorder = -1;
    for (int i = 0; i < nums; i++) {
        if (inorder[i] == root->m_val) {
            rootPositionOnInorder = i; //       
            break;
        }
    }
    if (rootPositionOnInorder == -1) {
        cout << "Input Error." << endl;
    }
    // Rebuild Left Tree
    root->m_pLeft = RebuildBinaryTree(preorder+1, inorder, rootPositionOnInorder);
    // Rebuild Right Tree
    root->m_pRight = RebuildBinaryTree(preorder+1+rootPositionOnInorder, inorder+1+rootPositionOnInorder, nums-rootPositionOnInorder-1);
    return root;
}이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.