2021-07-14 tree topic sorting

Posted by IMakeLousyCode on Mon, 17 Jan 2022 03:26:43 +0100

Source: PAT A1102

Title: reverse the tree from left to right

Idea: post order traversal and exchange the values of two nodes

Static writing( https://blog.csdn.net/xiaohuo0930/article/details/103928980)

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<string>
#include <iostream>
#include<stack>
#include <queue>
using namespace std;

struct node
{
	char data;
	node* lchild;
	node* rchild;
};

node* create()
{
	char ch;
	node* root;
	root = new node;
	cin >> ch;
	if (ch == '#')
		root = NULL;
	else
	{
		root->data = ch;
		root->lchild = create();
		root->rchild = create();
	}
	return root;
}

node* preorder(node* root)
{
	if (root == NULL)
		return root;
	cout << root->data;
	preorder(root->lchild);
	preorder(root->rchild);
}
node* postorder(node* root)
{
	if (root == NULL)
		return root;
	postorder(root->lchild);
	postorder(root->rchild);
	cout << root->data;
}
node* change(node* root)
{
	if (root == NULL)
		return root;
	swap(root->lchild, root->rchild);
	change(root->lchild);
	change(root->rchild);
	return root;
}


int main()
{
	node* root;
	root = create();
	preorder(root);
	cout << endl;
	preorder(change(root));
	cout << endl;
	postorder(change(root));
}

Source: leet101

Title: judge whether the tree is symmetrical

Idea: if the left node of the left subtree is the same as the right node of the right subtree, and the right node of the left subtree is the same as the left node of the right subtree, the tree is symmetrical

Termination condition: if one of the left and right nodes is empty, false will be returned, and if all nodes are empty, true will be returned

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<string>
#include <iostream>
#include<stack>
#include <queue>
using namespace std;

struct node
{
	char data;
	node* lchild;
	node* rchild;
};

node* create()
{
	char ch;
	node* root;
	root = new node;
	cin >> ch;
	if (ch == '#')
	{
		root = NULL;
	}
	else
	{
		root->data = ch;
		root->lchild = create();
		root->rchild = create();
	}
	return root;
}
void preorder(node *root)
{
	if (root == NULL)
	{
		return;
	}
	preorder(root->lchild);
	preorder(root->rchild);
}

bool check(node* root1, node* root2)
{
	//Termination conditions
	if (root1 == NULL && root2 == NULL)return true;
	else if (root1 == NULL && root2 != NULL)return false;
	else if (root1 != NULL && root2 == NULL)return false;
	//Single layer recursion
	if (root1->data != root2->data)return false;
	bool flag1=check(root1->lchild, root2->rchild);
	bool flag2=check(root1->rchild, root2->lchild);
	bool isSame = flag1 && flag2;
	return isSame;
}
bool isSymmetric(node* root)
{
	if (!root)
		return true;
	else return check(root->lchild,root->rchild);
}
int main()
{
	node* root;
	root = create();
	cout << isSymmetric(root);
}

Source: leet104

Title: get the maximum depth of the tree

The maximum depth of the tree is equal to the longest path from the root node to the leaf node

Idea: post order traversal, recursively get the largest side of the depth of the left and right subtrees of the node, and then + 1 get the depth of the root node.

Termination condition: when the node is empty, it returns 0

int maxDepth(node* root)
{
	int depth=0;
	if (root == NULL)
		return 0;
	left=maxDepth(root->left);
	right=maxDepth(root->right);
	if (left > right)
		return left++;
	else
		return right++;
}

Source: leet105

Title: Construction of post order arrangement from front order to middle order

Idea:

1. The front sequence is left and right, and the middle sequence traverses left, middle and right. Then, the first node of the preorder traversal is the middle node. If you find this node k from the middle order traversal, the left subtree node is on the left and the right subtree node is on the right.

2. Calculate the number of left nodes and record it as left

3. Divide the left and right subtrees: the first order left subtree: [p_start+1,p_start+left], the middle order left subtree: [in_start,k-1]

Front order right subtree: [p_start+left+1,p_end], middle order left subtree: [k+1,in_end]

4. Recursively return the root node to the left and right subtrees.

Source: PAT

Title: given the post order and middle order, find the pre order arrangement

Idea:

1. Post order traversal: left and right middle, middle order traversal: left, middle and right. ditto

The last node of post order traversal is the middle node, which is used to divide the middle order traversal to get the left subtree node

2. Post order traversal of left subtree: [postL,postL+left-1], middle order traversal of left subtree [inL,k-1]

Post order traversal of right subtree: [postL+left,postR-1], medium order traversal of right subtree [k+1,inR]

#include<cstdio>
#include<algorithm>
#include<cctype>
#include<string>
#include <iostream>
#include<stack>
#include <queue>
using namespace std;

int postorder[50] = { 0 };
int inorder[50] = { 0 };
int preorder[50] = { 0 };

struct node
{
	int data;
	node* lchild;
	node* rchild;
};
//Pre order, middle order and post order
node* create(int p_start,int p_end,int in_start,int in_end)
{
	//post, inorder, left, middle, right, pre, left and right
	//Recursive termination condition returns null if the length of the subsequent sequence is less than or equal to 0
	//One step logic: take the root node of the preorder traversal as the division to find the left and right boundaries of the middle order traversal
	if (p_start > p_end)
		return NULL;
	node* root = new node;
	root->data = preorder[p_start];
	//Traversing the left subtree boundary in order in the record
	int k = 0;
	for (k = 0; k <= in_end; k++)
	{
		if (preorder[p_start] == inorder[k])
		{
			break;
		}
	}
	int left = k - in_start;//Left node number
	root->lchild = create(p_start + 1, p_start + left, in_start, k-1);
	root->rchild = create(p_start + left + 1, p_end, k + 1, in_end);
	return root;
}
//After order
//node* create(int postL, int postR, int inL,int inR)
//{
//	if (postL > postR)
//		return NULL;
//	node* root = new node;
//	root->data = postorder[postR];// The last node of post order traversal is the root node
//	int k;// Record the position of traversal node in root order
//	for (k = 0; k <= inR; k++)
//	{
//		if (postorder[postR] == inorder[k])
//		{
//			break;
//		}
//	}
//	int num_left = k - inL;// Number of left nodes
//	root->lchild = create(postL, postL + num_left - 1, inL, k - 1);
//	root->rchild = create(postL + num_left, postR - 1, k + 1, inR);
//	return root;
//}

void post_order(node* root)
{
	if (root == NULL)
		return;
	post_order(root->lchild);
	post_order(root->rchild);
	cout << root->data<<' ';
}
void pre_order(node* root)
{
	if (root == NULL)
		return;
	cout << root->data << ' ';
	pre_order(root->lchild);
	pre_order(root->rchild);
}
int main()
{
	int n;
	scanf_s("%d", &n);
	for (int i = 0; i < n; i++)
	{
		scanf_s("%d", &preorder[i]);
	}
	for (int i = 0; i < n; i++)
	{
		scanf_s("%d", &inorder[i]);
	}
	node* l = create(0, n - 1, 0, n - 1);
	post_order(l);
}



Source: leet114

Title: expand the binary tree into a linked list (one side representation)

Idea: for the node on the right side of each root node, temporarily traverse and store the left subtree, traverse the rightmost node of the right subtree, and insert the left subtree into the rightmost node

//void flatten(node* root)
//{
//    node* tmp = root;
//    if (root == nullptr)return;
//    while (tmp)
//    {
//        node* p = tmp->right;
//        tmp->right = tmp->left;
//        tmp->left = nullptr;
//        node* t = tmp;
//        while (t->right)
//            t = t->right;
//        t->right = p;
//        tmp = tmp->right;
//    }

Source: leet222

Title: get the total number of nodes of the tree

Idea: level traversal, get a node counter and add 1

int countNodes(TreeNode* root)
{
    queue<TreeNode*>que;
    if (root != nullptr)que.push(root);
    int res = 0;
    while (!que.empty())
    {
        int size = que.size();
        for (int i = 0; i < size; i++)
        {
            TreeNode* node = que.front();
            que.pop();
            res++;
            if (node->left)que.push(node->left);
            if (node->right)que.push(node->right);
        }
    }
    return res;
}