1. 程式人生 > >【模板】二叉搜索樹

【模板】二叉搜索樹

for truct false define queue ios size struct 刪除節點

二叉搜索樹:對於二叉樹中的任意節點,左子樹中所有的值都小於當前位置的值,右子樹中所有的值都大於當前位置的值。

操作:

1.插入一個數值。

2.查詢是否包含某個數值。

3.刪除某個數值。

插入和查找是差不多的,都是比當前值(要找的值)大就往左走,否則就往右走,直到找到為止。

最復雜的操作是刪除某個節點,不過可以分為3種情況來討論:

1.需要刪除的節點沒有左子樹,那就把右子樹提上去。

2.需要刪除的節點的左子樹沒有右子樹,那就把左子樹提上去。

3.其他情況,把左子樹中最大的節點提到當前刪除的節點的位置。

所有操作的時間復雜度都是O(log(n))。

還是比較高效的一種數據結構。

代碼:

#include <iostream>
#include <algorithm>
#include <map>
#include <vector>
#include <set>
#include <math.h>
#include <queue> 
using namespace std;
typedef long long ll;
#define INF 2147483647

//表示節點的結構體 
struct node{
    int val;
    node *lch, *rch;
};

//如果小於當前節點往左走,否則往右走,直到走到空為止,把要插入的節點放在這。 //返回值意義是更新當前子樹,想象一下從最下層開始返回的情況。 node *insert(node *p,int x){ if(p == NULL){ node *q = new node; q->val = x; q->lch = q->rch = NULL; return q; }else{ if(x < p->val) p->lch = insert(p->lch, x);
else p->rch = insert(p->rch, x); return p; } } //查找數值x。 //每一個節點當做一棵子樹,如果當前節點不是就找它的左右子樹。 bool find(node *p,int x){ if(p == NULL) return false; else if(x == p->val) return true; else if(x < p->val) return find(p->lch, x); else return find(p->rch, x); } node *remove(node *p, int x){ if(p == NULL) return NULL; //當前子樹沒有找到,如果一個節點的左右子樹都返回NULL表明當前子樹沒有找到 else if(x < p->val) p->lch = remove(p->lch, x); //向左走 else if(x > p->val) p->rch = remove(p->rch, x); //向右走 //以下為找到了的情況 //左子樹為空,先保存右子樹,再刪除當前節點,把右子樹直接掛在刪除節點的原先位置。 else if(p->lch == NULL){ node *q = p->rch; delete p; return q; //左子樹的右子樹為空,把刪除節點的左子樹掛在當前位置,把刪除節點的右子樹掛在當前位置的右邊 //這樣保證了搜索樹的性質 }else if(p->lch->rch == NULL){ node *q = p->lch; q->rch = p->rch; delete p; return q; }else{ //找到刪除節點左子樹的最右邊的節點,即左子樹中的最大值 q->rch node *q; for(q = p->lch;q->rch->rch != NULL; q = q->rch); //把最大值節點q->rch用r保存下來,把最大值節點的左子樹提上來 node *r = q->rch; q->rch = r->lch; //把最大值節點r放在了原先刪除節點的位置 r->lch = p->lch; r->rch = p->rch; delete p; return r; } return p; } int main(){ return 0; }

【模板】二叉搜索樹