劍指offer---二叉搜索樹與雙向鏈表

題目描述

輸入一棵二叉搜索樹,將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的結點,只能調整樹中結點指針的指向。
解法一:
因題目中不允許創建任何新的結點,故可以創建一個數組來存放所有的結點。
即通過中序遍歷求出排序列表,然後遍歷數組,依次爲每個結點的左右指針賦值。

//中序遍歷 
void in_order(TreeNode* root,vector<TreeNode*> &v){
	if(root != NULL){
		in_order(root->left,v);
		v.push_back(root);
		in_order(root->right,v);
	}
} 
//二叉搜索樹與雙向鏈表 
TreeNode* Convert(TreeNode* pRootOfTree){
	if(pRootOfTree==NULL){
		return NULL;
	}
	vector<TreeNode*> v;
	in_order(pRootOfTree,v);
	TreeNode* p = v[0];
	for(int i = 1;i < v.size();i++){
		p->right = v[i];
		v[i]->left = p;
		p = v[i];
	}
	return v[0];
}

解法二:
通過二叉搜索樹的性質,可知,雙向鏈表的左指針指向的結點爲該結點的左子樹的最右邊的結點,右指針指向的結點爲該結點的右子樹的最左邊的結點。
故可以通過遞歸的方式來實現。

//找最右結點 
TreeNode* find_right(TreeNode* root){
	while(root->right){
		root = root->right;
	}
	return root;
}

//二叉搜索樹與雙向鏈表 
TreeNode* Convert(TreeNode* pRootOfTree){
	if(pRootOfTree == NULL){
		return NULL;
	}
	TreeNode* leftNode = Convert(pRootOfTree->left);//找到最左邊結點 
	TreeNode* rightNode = Convert(pRootOfTree->right);
	TreeNode* head = leftNode;//鏈表的頭部 
	if(leftNode){
		leftNode = find_right(leftNode);
	}else{
		head = pRootOfTree;
	}
	//構造雙向鏈表
	pRootOfTree->left = leftNode;
	pRootOfTree->right = rightNode; 
	if(leftNode){
		leftNode->right = pRootOfTree; 
	}
	if(rightNode){
		rightNode->left = pRootOfTree;
	}
	return head;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章