c++--이진 트리 응용 프로그램

1. 이진 트리에 따라 문자열  버튼을 만듭니다.

이진 트리의 루트 노드 루트가 주어지면 선주문 순회 방법을 사용하여 이진 트리를 대괄호와 정수로 구성된 문자열로 변환하고 구성된 문자열을 반환하십시오.

빈 노드는 빈 괄호 쌍 "()"으로 표시됩니다. 변환 후 문자열과 원래 이진 트리 간의 일대일 매핑에 영향을 주지 않는 모든 빈 괄호 쌍은 생략되어야 합니다.

출처: LeetCode

class Solution {
public:
    string tree2str(TreeNode* root) 
    {
        //根据前序遍历确定字符串
        if(root==nullptr)
            return "";
        string tree=to_string(root->val);
        //只有左右子树都为空不保留括号,其他情况都保留括号
        if(root->left||root->right)
        {
            tree+='(';
            tree+=tree2str(root->left);
            tree+=')'; 
        }

         if(root->right)
        {
            tree+='(';
            tree+=tree2str(root->right);
            tree+=')'; 
        }
        return tree;
    }
};

2. 이진 트리 계층 순회

이진 트리의 루트 노드가 주어지면 root해당 노드 값의 레벨 순서 순회를 반환합니다 . (즉, 레이어별로, 왼쪽에서 오른쪽으로 모든 노드를 방문합니다).

예시 1:

입력: 루트 = [3,9,20,null,null,15,7]
출력: [[3],[9,20],[15,7]]

예시 2:

입력: 루트 = [1]
출력: [[1]]

예시 3:

입력: 루트 = []
출력: []

출처: LeetCode

class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) 
    {
        //用队列来确定
        queue<TreeNode*> TreeNode1;
        vector<vector<int>> vv;
        int levesize=0;
        if(root)
        {
            TreeNode1.push(root);
            levesize=1;
        }
        while(!TreeNode1.empty())
        {
            vector<int> v;
            for(int i=0;i<levesize;i++)
            {
                TreeNode* front= TreeNode1.front();
                TreeNode1.pop();

                v.push_back(front->val);

                if(front->left)
                { 
                    TreeNode1.push(front->left);
                }
                if(front->right)
                {
                    
                    TreeNode1.push(front->right);
                }
            }
            vv.push_back(v);
            //TreeNode.pop();
            levesize=TreeNode1.size();
        }
        return vv;

    }
};

3. 이진 트리의 가장 가까운 공통 조상은 버튼입니다

이진 트리가 주어지면 트리에서 지정된 두 노드의 가장 가까운 공통 조상을 찾습니다.

바이두 백과사전에서 가장 가까운 공통 조상에 대한 정의는 다음과 같습니다. "뿌리 트리 T의 두 노드 p와 q에 대해 가장 가까운 공통 조상은 노드 x로 표현되며, x는 p와 q의 조상이고 깊이는 x는 가능한 한 큽니다. (A 노드는 자신의 조상이 될 수도 있습니다.)

예시 1:

입력: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
출력: 3
설명: 노드 5와 노드 1의 가장 가까운 공통 조상 노드 3입니다.

예시 2:

입력: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
출력: 5
설명: 노드 5와 4의 가장 가까운 공통 조상은 다음과 같습니다. 노드 5. 정의에 따르면 가장 가까운 공통 조상 노드는 노드 자체가 될 수 있습니다.

예시 3:

입력: root = [1,2], p = 1, q = 2
출력: 1

출처: LeetCode

class Solution {
public:
    bool find_node(TreeNode* root, TreeNode* p, stack<TreeNode*>& path)
    {
        if(root==nullptr)
            return false;
       
        path.push(root);

        if (root == p)
            return true;
       if( find_node(root->left, p, path))
            return true;
        
       if( find_node(root->right, p, path))
            return true;
        path.pop();
        return false;
    }

    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q)
    {
         

         //使用两个栈存放二叉树要找的数据,
        stack<TreeNode*> ppath;
        stack<TreeNode*> qpath;
        find_node(root, p, ppath);
        find_node(root, q, qpath);
        //确定长度
        while (ppath.size() > qpath.size())
        {
            ppath.pop();
        }
        while (ppath.size() < qpath.size())
        {
            qpath.pop();
        }

        while (ppath.size() == qpath.size())
        {
            if (ppath.top() == qpath.top())
            {
                return ppath.top();
            }
            ppath.pop();
            qpath.pop();
        }
        return nullptr;

    }
};

4.  이진 검색 트리와 이중 연결 리스트

이진 검색 트리를 입력하고 이진 검색 트리를 정렬된 이중 연결 목록으로 변환합니다. 아래 그림과 같이

데이터 범위: 입력 이진 트리의 노드 수 0≤n<10000<n<1000, 이진 트리의 각 노드 값 0<val<10000<val<1000
요구 사항: 공간 복잡도 O(1)O( 1) (즉, 원래의 트리 연산에서), 시간 복잡도 O(n)O(n)

알아채다:

1. 새 노드를 생성할 수 없으며 트리에서 노드 포인터의 포인팅만 조정할 수 있습니다. 변환이 완료된 후 트리 노드의 왼쪽 포인터는 선행 노드를 가리켜야 하고 트리 노드의 오른쪽 포인터는 후속 노드를 가리켜야 합니다. 2. 포인터를 연결된 노드의 첫 번째 노드로 반환합니다
. 목록
3. 함수에 의해 반환된 TreeNode에는 왼쪽 및 오른쪽 포인터가 있으며 실제로 이중 연결 목록의 데이터 구조로 볼 수 있습니다.

4. 이중 연결 목록을 출력할 필요가 없습니다. 프로그램은 반환 값에 따라 자동으로 인쇄합니다.

설명을 입력하세요:

이진 트리의 루트 노드

반환 값 설명:

이중 연결 리스트의 헤드 노드 중 하나입니다.

실시예 1

입력하다:

{10,6,14,4,8,12,16}
반환 값:
왼쪽에서 오른쪽으로: 4,6,8,10,12,14,16; 오른쪽에서 왼쪽으로: 16,14,12,10,8,6,4;
class Solution {
	void Indor(TreeNode* cur,TreeNode*& prev)
	{
        //确定双向链表
		if(cur==nullptr)
			return;
		Indor(cur->left,prev);
		cur->left=prev;
		
		if(prev)
			prev->right=cur;
		prev=cur;
		Indor(cur->right,prev);
		
	}
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
	{
		TreeNode* prev=nullptr;
		Indor(pRootOfTree,prev);
        //判断头结点
		TreeNode* head=pRootOfTree;
		while(head&&head->left)
		{
			head=head->left;
		}
		return head;
    }
};

5. 선순서와 중순서로부터 이진 트리 링크를 결정합니다.

두 개의 정수 배열 preorder와 inorder가 주어지면, preorder는 이진 트리의 선순 순회이고 inorder는 동일한 트리의 중위 순회이며, 이진 트리를 구성하고 해당 루트 노드를 반환합니다.

예시 1:

입력: 선주문 = [3,9,20,15,7], 중순 = [9,3,15,20,7]
출력: [3,9,20,null,null,15,7]

예시 2:

입력: 선주문 = [-1], 중순 = [-1]
출력: [-1]

출처: LeetCode

class Solution {
    TreeNode* buildTree(vector<int>& preorder,vector<int>& inorder,int& prie,
                    int inbegin,int inend)
        {
            if(inbegin>inend)//结束条件
                return nullptr;

            TreeNode* root=new TreeNode(preorder[prie]);
            int rooti=inbegin;
            while(rooti<=inend)
            {
                if(preorder[prie]==inorder[rooti])
                    break;
                rooti++;
            } 
            ++prie;

            root->left=buildTree(preorder,inorder,prie,inbegin,rooti-1);
            root->right=buildTree(preorder,inorder,prie,rooti+1,inend);

            return root;

        }

public:
    TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) 
    {
        int i=0;
        TreeNode* root=buildTree(preorder,inorder,i,0,inorder.size()-1);
        return root;
    }
};

6. 이진 트리 강제 버튼을 결정하기 위한 순차 및 후차 

class Solution {
    TreeNode* _buildTree(vector<int>& inorder,vector<int>& postorder,
                        int& n,int inbegin,int inend)
    {
        if(inbegin>inend)
            return nullptr;

        TreeNode* root=new TreeNode(postorder[n]);

        int rooti=inbegin;

        while(rooti<=inend)
        {
            if(postorder[n]==inorder[rooti])
                break;
            rooti++;
        }
        n--;

        root->right=_buildTree(inorder,postorder,n,rooti+1,inend);//先右再左
        root->left=_buildTree(inorder,postorder,n,inbegin,rooti-1);
        return root;
    }
public:
    TreeNode* buildTree(vector<int>& inorder, vector<int>& postorder) 
    {
        int n=postorder.size()-1;

        return _buildTree(inorder,postorder,n,0,postorder.size()-1);
    }
};

7. 이진 트리 후순 순회 반복  알고리즘

이진 트리의 루트 노드 루트가 주어지면 해당 노드 값의 후위 순회를 반환합니다.

예시 1:

입력: 루트 = [1,null,2,3]
출력: [3,2,1]

출처: LeetCode

class Solution {
public:
    vector<int> postorderTraversal(TreeNode* root) 
    {
        stack<TreeNode*> st;
        vector<int> nums;
        TreeNode* cur=root;
        TreeNode* prev=nullptr;

        while(cur||!st.empty())
        {
            while(cur)
            {
                st.push(cur);
                cur=cur->left;
            }
            TreeNode* top=st.top();
            if(top->right==nullptr||top->right==prev)//防止重复遍历
            {
                prev=top;
                st.pop();
                nums.push_back(top->val);
            }
            else
            {
                cur=top->right;
            }
            
        }
        return nums;
    }
};

추천

출처blog.csdn.net/weixin_66828150/article/details/132128427