1. 程式人生 > >二叉搜尋樹的相關操作

二叉搜尋樹的相關操作

二叉搜尋樹是一些AVL,RB-tree等的基礎,所以瞭解二叉搜尋樹的基本操作很重要。

定義:

若它的左子樹不空,則左子樹上所有結點的值均小於它的根結點的值; 若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值; 它的左、右子樹也分別為二叉排序樹。

這裡給出自己畫的一個二叉樹,不知道有啥好的畫圖軟體

在這裡插入圖片描述

首先我們得知道如何驗證是否是一顆標準的二叉樹,中序遍歷,中序遍歷的二叉搜尋樹肯定死有序的,並且是升序。

首先宣告二叉樹的節點

struct TreeNode 
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

查詢二叉搜尋樹的節點

那麼如何在一顆二叉搜尋樹中找到特定的節點,因為根節點比左節點大,比右節點小,只需要和根節點比較即可。

//root表示當前遍歷的根節點 pre為遍歷的上一個節點,target為目標節點
bool SearchBST(TreeNode* root,int key,TreeNode* &pre,TreeNode* &target)
{
	if (!root)
	{
		target = pre;
		return false;
	}
	if (root->val == key)
	{
		target = root;
		return true;
	}
	pre = root;
	if (root->val < key)
		SearchBST(root->right, key, pre, target);
	else
		SearchBST(root->left, key, pre, target);
}

刪除二叉搜尋樹的節點

刪除二叉樹的節點有三種情況

1: 當這個節點的右子樹為空,那麼直接用該節點的左子樹覆蓋即可。

2: 當這個節點的左子樹為空,那麼直接用該節點的右子樹覆蓋即可。

3:當這個節點左右子樹都存在的時候,則只需要找到中序遍歷的下一個節點去替代他即可,所以從右子樹開始找,然後一直找左節點,即是該節點在中序遍歷中的下一個節點B,然後遍歷的時候位置B的前一個節點,最後置為NULL即可。

程式碼:

void DeleteBSTnode(TreeNode* &root,int key)
{
	TreeNode* s;
	if (root == NULL)
	{
		return;
	}
	if (root->val == key)
	{
		//cout << " 找到了該值" << endl;
		cout << root->val << endl;
		if (root->right == NULL)
		{
			//cout << "窩在這裡" << endl;
			s = root;
			root = root->left;
			free(s);
		}
		else if (root->left == NULL)
		{
			s = root;
			root = root->right;
			free(s);
		}
		//如果左右子節點都有
		else
		{
			TreeNode* pre;
			pre = root;
			s = root->right;
			while (s->left)
			{
				pre = s;
				s = s->left;
			}
			root->val = s->val; 
			pre->left = NULL;
			free(s);
		}
	}
	else if (root->val<key) DeleteBSTnode(root->right, key);
	else DeleteBSTnode(root->left, key);
}

插入節點到二叉搜尋樹

其實和遍歷二叉樹沒多大區別,找到該插入的位置即可。如果樹為空,那麼這個新節點為根節點。

程式碼:

void InsertBSTnode(TreeNode* root, int key)
{
	TreeNode* newNode = new TreeNode(key);
	if (root == NULL)
	{
		newNode = root;
		return;
	}
	TreeNode* pre = NULL;
	TreeNode* target = NULL;
	if (SearchBST(root, key, pre, target))
	{
		cout << "該節點已經存在" << endl;
		return;
	}
	else
	{
		TreeNode* plastNode = NULL;
		while(root)
		{
			plastNode = root;
			if (root->val > key) root = root->left;
			else root = root->right;
		}
		if (plastNode->val < key) plastNode->right = newNode;
		else plastNode->left = newNode;
	}
}

完整的程式碼,包括測試程式碼

#include "stdafx.h"
#include<iostream>
#include<vector>
#include<stack>
#include<map>
#include<string>
#include<queue>
#include<set>
#include<algorithm>
#include<malloc.h>
#include<stdlib.h>
#include<functional>
using namespace std;


struct TreeNode 
{
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};


void mid_order(TreeNode* Troot)
{
	if (Troot) 
	{
		mid_order(Troot->left);
		cout << Troot->val << " ";
		mid_order(Troot->right);
	}
}


//root表示當前遍歷的根節點 pre為遍歷的上一個節點,target為目標節點
bool SearchBST(TreeNode* root,int key,TreeNode* &pre,TreeNode* &target)
{
	if (!root)
	{
		target = pre;
		return false;
	}
	if (root->val == key)
	{
		target = root;
		return true;
	}
	pre = root;
	if (root->val < key)
		SearchBST(root->right, key, pre, target);
	else
		SearchBST(root->left, key, pre, target);
}



void DeleteBSTnode(TreeNode* &root,int key)
{
	TreeNode* s;
	if (root == NULL)
	{
		return;
	}
	if (root->val == key)
	{
		//cout << " 找到了該值" << endl;
		cout << root->val << endl;
		if (root->right == NULL)
		{
			//cout << "窩在這裡" << endl;
			s = root;
			root = root->left;
			free(s);
		}
		else if (root->left == NULL)
		{
			s = root;
			root = root->right;
			free(s);
		}
		//如果左右子節點都有
		else
		{
			TreeNode* pre;
			pre = root;
			s = root->right;
			while (s->left)
			{
				pre = s;
				s = s->left;
			}
			root->val = s->val; 
			pre->left = NULL;
			free(s);
		}
	}
	else if (root->val<key) DeleteBSTnode(root->right, key);
	else DeleteBSTnode(root->left, key);
}


void InsertBSTnode(TreeNode* root, int key)
{
	TreeNode* newNode = new TreeNode(key);
	if (root == NULL)
	{
		newNode = root;
		return;
	}
	TreeNode* pre = NULL;
	TreeNode* target = NULL;
	if (SearchBST(root, key, pre, target))
	{
		cout << "該節點已經存在" << endl;
		return;
	}
	else
	{
		TreeNode* plastNode = NULL;
		while(root)
		{
			plastNode = root;
			if (root->val > key) root = root->left;
			else root = root->right;
		}
		if (plastNode->val < key) plastNode->right = newNode;
		else plastNode->left = newNode;
	}
}

int main()
{

	TreeNode* p1 = new TreeNode(8);
	TreeNode* p2 = new TreeNode(5);
	TreeNode* p3 = new TreeNode(10);
	TreeNode* p4 = new TreeNode(4);
	TreeNode* p5 = new TreeNode(7);
	TreeNode* p6 = new TreeNode(9);
	TreeNode* p7 = new TreeNode(12);
	TreeNode* p8 = new TreeNode(6);
	TreeNode* p9 = new TreeNode(11);

	p1->left = p2;
	p1->right = p3;
	p2->left = p4;
	p2->right = p5;
	p3->left = p6;
	p3->right = p7;
	p5->left = p8;
	p7->left = p9;

	TreeNode*  root = p1;

	mid_order(root);
	cout << endl;

	/*TreeNode* pre = NULL;
	TreeNode* target = NULL;

	cout << SearchBST(root, 7, pre, target) << endl;*/

	//cout << target->val << " "<< target->left->val << endl;
//	if (target->right)  cout << target->right->val << endl;

//	cout << root->val << endl;

	//DeleteBSTnode(root, 5);
	//mid_order(root);
	//cout << endl;

	int key = 0;
	while (key != -1)
	{
		cout << "請輸入你要插入的值" << endl;
		cin >> key;
		InsertBSTnode(root, key);
		mid_order(root);
		cout << endl;
	}
	return 0;
}