二叉搜尋樹的相關操作
阿新 • • 發佈:2018-12-10
二叉搜尋樹是一些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;
}