1. 程式人生 > >二叉搜尋樹的插入,刪除,遍歷操作詳解

二叉搜尋樹的插入,刪除,遍歷操作詳解

TreeNode* findNodeInSearchBT(TreeNode*root, int k, TreeNode**pa = nullptr)
{
	//這裡是不需要進行null判斷的,因為後面隱式的判斷了是否為null
	while (root != nullptr)
	{
		if (k > root->value)
		{
			*pa = root;
			root = root->rh;
		}
		else if (k < root->value)
		{
			*pa = root;
			root = root->le;
		}
		else
			break;  //找到了相應的節點
	}


	//找到了相應的節點就返回該節點,若不存在該節點的父節點則返回nullptr
	return root;
}

bool deleteNodeInSearchBT(TreeNode*root, int k)
{
	TreeNode*PatoDelete = nullptr;     //用於儲存D的父節點
	TreeNode* toDelete = findNodeInSearchBT(root, k, &PatoDelete);    //找到D節點

	//需要先判斷一下是否找到了這個節點,沒找到就直接返回false
	if (nullptr == toDelete)
		return false;

	//D節點沒有左子樹,或者左右子樹都沒有  第一第二中情況
	if (toDelete->le == nullptr)
	{
		if (k < PatoDelete->value)
			PatoDelete->le = toDelete->rh;   	//需要把這個父節點的左節點替換為用來替換的節點
		else
			PatoDelete->rh = toDelete->rh;    //這裡就是右子樹需要被替換了
		delete toDelete;
		return true;
	}

	//D節點沒有右子樹第三種情況
	if (toDelete->rh == nullptr)
	{
		if (k < PatoDelete->value)
			PatoDelete->le = toDelete->le;   	//需要把這個父節點的左節點替換為用來替換的節點
		else
			PatoDelete->rh = toDelete->le;    //這裡就是右子樹需要被替換了
		delete toDelete;
		return true;
	}

	//D節點左右子樹都有,第四種情況
	auto minInRh = toDelete;
	TreeNode* minInRhpa = nullptr;    //這裡用來儲存用來替換的節點的父節點
	while (minInRh->le != nullptr)
	{
		minInRhpa = minInRh;
		minInRh = minInRh->le;
	}   //找到X節點,儲存了其父節點

	//其實這裡就是對X做了一次刪除操作,只不過這個X一定是第一種或者第二種情況
	minInRhpa->le = minInRh->rh;  //這裡右子樹是否非空是沒有關係的;直接對X使用第一或者第二中方法刪除,然後用X替換D
	 //需要把用來替換的節點的左右子樹換成被刪除子樹的左右子樹,不然就把樹給弄斷了
	minInRh->le = toDelete->le;
	minInRh->rh = toDelete->rh;

	//一切準備就緒,可以替換了
	if (k < PatoDelete->value)
		PatoDelete->le = minInRh;   	//需要把這個父節點的左節點替換為用來替換的節點
	else
		PatoDelete->rh = minInRh;    //這裡就是右子樹需要被替換了

//注意不要忘記釋放空間了
	delete toDelete;

	//走到了這裡說明一切都很順利,可以返回true了
	return true;
}

三,遍歷操作