Statistical leaf node 21

Keywords: C++ Algorithm data structure

1, Title Description

Description

The preorder traversal and inorder traversal of a binary tree are given, and the number of leaf nodes of the corresponding binary tree is counted. This question requires the use of a binary linked list, otherwise even if it passes, points will be deducted as appropriate.

Input

Input two lines of string composed of only uppercase letters, representing the preorder traversal and inorder traversal of binary tree respectively.

Output

Output a number per line, indicating the number of leaf nodes of the tree.

example:

input:

ABCD
ABCD


output:

1

2, Problem solving ideas

1. Build tree

Given the pre order and middle order, a unique binary tree can be established.

The overall implementation idea is through recursive partition,

Specific ideas:

(1) Priority can determine the root node

(2) If you find the root node in the middle order, you can divide the left and right subtrees (the left is the left subtree and the right is the right subtree)

(3) Treat the left and right subtrees as a new tree and call recursively again

(4) If the start subscript of the input substring > end subscript, the substring is empty and NUL is returned

Function implementation:

//Create tree
//pre is the starting subscript of the preorder prea the ending subscript of the preorder preb the ending subscript of the preorder mid the middle order mida the beginning of the middle order midb the ending of the middle order
TreeNode* BuildTree(string pre, string mid, int prea, int preb, int mida, int midb)
{
	if (prea > preb)//The substring is empty
	{
		return NULL;
	}
	else
	{
		TreeNode* root = new TreeNode;//Set root node
		root->data = pre[prea];//The first is the root node
		int tag = mida;//Find the position of the root node in the middle order arrangement
		while (mid[tag] != root->data)
		{
			tag++;
		}
		int llength;//Calculate the length of the left substring
		llength = tag - mida;
		
		root->lchild = BuildTree(pre, mid, prea + 1, prea + llength, mida, tag - 1);
		root->rchild = BuildTree(pre, mid, prea + llength + 1, preb, tag + 1, midb);
		
		return root;
	}
}

(in order to look more intuitive, I deleted the debug output statement compared with the complete code posted at the end)

Several explanations:

(1) Parameters of function

pre is the start subscript of the preamble prea and the end subscript of the preamble preb   mid order   mida middle order start   End of midb sequence

(2) Parameters in recursive call

Left substring:

Preamble start = old prea+1 (the first is marked as the root node)    End = old PREA + length (left substring length)

("end" can be understood as "start + left substring length - 1")

Middle sequence start = old mida   End = tag (root) - 1

Right substring:

Preamble start = old PREA + length (left substring length) + 1   End = old preb

Middle order start = tag (root) + 1   End = old midb

If you don't quite understand it, start painting, it's easy to understand.

2. Calculate the number of leaf nodes

Idea:

Recursive implementation of preorder traversal, in which the judgment of leaf nodes is added.

Function implementation:

int CountLeaf(TreeNode* root)//Calculating the number of leaf nodes and tail recursion saves space
{
	if (root == NULL)
		return 0;
	else if (root->lchild == NULL && root->rchild == NULL)
	{
		cout << root->data << "  ";
		return 1;
	}
	else
	{
		cout << root->data << "  ";
		return CountLeaf(root->lchild) + CountLeaf(root->rchild);
	}
}

The idea is very simple, but one thing to note is that this function uses tail recursion,

I didn't do that at first, which resulted in timeout.  

int CountLeaf(TreeNode* root,int& count)
{
	if (root == NULL)
		return 0;
	else
	{
		if (root->lchild != NULL)
			CountLeaf(root->lchild, count);
		if(root->rchild!=NULL)
			CountLeaf(root->rchild, count);
		else if (root->lchild == NULL && root->rchild == NULL)
			count++;
	}
}

3, Complete code

#include<iostream>
#include<string>

using namespace std;

//Node definition
struct TreeNode
{
	char data;
	TreeNode* lchild,* rchild;
};

//Create tree
TreeNode* BuildTree(string pre, string mid, int prea, int preb, int mida, int midb)
{
	if (prea > preb)//The substring is empty
	{
		cout << "The substring is empty" << endl;
		return NULL;
	}
	else
	{
		TreeNode* root = new TreeNode;//Set root node
		root->data = pre[prea];//The first is the root node
		int tag = mida;//Find the position of the root node in the middle order arrangement
		while (mid[tag] != root->data)
		{
			tag++;
		}
		int llength;//Calculate the length of the left substring
		llength = tag - mida;
		printf("Now in%c Node, left substring length is%d\n", root->data, llength);//For debug ging convenience
		printf("establish%c Left subtree of:\n", root->data);
		printf("prea=%d,preb=%d,mida=%d,midb=%d\n", prea + 1, prea + llength, mida, tag - 1);
		
		root->lchild = BuildTree(pre, mid, prea + 1, prea + llength, mida, tag - 1);
		
		printf("establish%c Right subtree of:\n", root->data);
		printf("prea=%d,preb=%d,mida=%d,midb=%d\n", prea + llength + 1, preb, tag + 1, midb);
		
		root->rchild = BuildTree(pre, mid, prea + llength + 1, preb, tag + 1, midb);
		
		return root;
	}
}

int CountLeaf(TreeNode* root)//Calculating leaf node tail recursively saves space
{
	if (root == NULL)
		return 0;
	else if (root->lchild == NULL && root->rchild == NULL)
	{
		cout << root->data << "  ";
		return 1;
	}
	else
	{
		cout << root->data << "  ";
		return CountLeaf(root->lchild) + CountLeaf(root->rchild);
	}
}

int main()
{
	string pre,mid;
	cin >> pre;//Preorder
	cin >> mid;//Middle order
	printf("pre.length()=%d,mid.length()=%d", pre.length(), mid.length());
	TreeNode* root= BuildTree(pre, mid, 0, pre.length()-1, 0, mid.length()-1);
	cout << CountLeaf(root);
	return 0;
}

In fact, there is another point to pay attention to in the main function, that is, when calling the BuildTree function,

BuildTree(pre, mid, 0, pre.length()-1, 0, mid.length()-1);

Remember - 1. Although it was a small point, I had to look for it for a long time to find the problem orz

In the complete code, I mix cin, cout and printf, which is not recommended!!!! Don't do this!!!

(but I'm too lazy to change... Mainly because scanf is very bad)

Posted by freelancedeve on Sat, 27 Nov 2021 18:56:45 -0800