構造中序線索二叉樹

主要是利用二叉樹的空指針域,若爲空,使左指針指向前驅,並標記ltag爲1;使右指針指向後驅,並標記rtag爲1;

要注意的是構造結束後,此時pre指向最後一個結點,此時需記得pre->right = nullptr, pre->rtag = 1。否則這棵樹的右子樹無法遍歷;

這樣使得這些指針域不至於浪費,並能夠加快查找結點前驅和後繼的速度。

#include <iostream>
#include <string>
using namespace std;

typedef int ElementType;
typedef struct TreeNode{
	ElementType val;
	TreeNode* left;
	TreeNode* right;
	int ltag;
	int rtag;
	TreeNode(ElementType x):val(x), left(nullptr), right(nullptr)
		, ltag(0), rtag(0){}			
}*ThreadTree;

void visit(TreeNode* node)
{
	cout << node->val << " ";
}

void inOrder(ThreadTree root)
{
	if( root ){
		inOrder(root->left);
		visit(root);
		inOrder(root->right);
	}
}

ThreadTree BST_Insert(ThreadTree root, int n = 0)
{
	cout << "Please input " << n << " value to insert BST:\n";
	while( n-- )
	{
		ElementType x;
		cin >> x;
		ThreadTree t = new TreeNode(x);
		if( root == nullptr ){
			root = t;
			continue;
		}

		ThreadTree p = root, pre;
		while( p ){
			pre = p;
			if( x < p->val )
				p = p->left;
			else
				p = p->right;
		}
		if( x < pre->val ) pre->left = t;
		else pre->right = t;
	}
	return root;	
}

//	構造中序線索二叉樹,注意參數是引用 
void InThread(ThreadTree& p, ThreadTree& pre)
{
	if( p ){
		InThread(p->left, pre);		//左子樹線索化 
		if( !p->left ){				//左結點爲空,指向前驅 
			p->left = pre;
			p->ltag = 1;
		}
		if( pre && !pre->right ){	//右節點爲空,指向後繼 
			pre->right = p;
			pre->rtag  = 1;
		}
		pre = p;					//當前結點轉爲前驅 
		InThread(p->right, pre);	//右子樹線索化 
	}				
}  

bool createInThread(ThreadTree root)
{
	ThreadTree pre = nullptr;
	if( root ){
		InThread(root, pre);
		pre->right = nullptr;		//最後一個結點,沒有後繼 
		pre->rtag = 1;
		return true;
	}
	return false;
}

//	中序遍歷第一個節點,是最左下的結點(不一定是葉節點) 
TreeNode* firstNode(ThreadTree p)
{
	while( p->ltag == 0 )
		p = p->left;
	return p;
}

//	後繼結點,若無直接後繼,則返回線索後繼 
TreeNode* nextNode(ThreadTree p)
{
	if( p->rtag == 0 )
		return firstNode(p->right);
	else
		return p->right;	
}

void Thread_inOrder(ThreadTree root)
{
	for(TreeNode* p = firstNode(root); p; p = nextNode(p))
		visit(p);
	cout << "\n";	
}

//7
//6 2 8 1 4 7 3

int main( )
{
	int n;
	cin >> n;
	
	ThreadTree root = nullptr;
	root = BST_Insert(root, n);
	inOrder(root);
	
	if( createInThread(root) ){
                cout << "\n";
		Thread_inOrder(root);	
	}
	
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章