一天一道演算法題 BST二叉查詢樹

2022-05-06 17:33:38 字數 2170 閱讀 4379

您需要寫一種資料結構,來維護一些數( 都是 10^9以內的數字)的集合,最開始時集合是空的。其中需要提供以下操作,操作次數 q不超過 10^4:

查詢 x數的排名(排名定義為比當前數小的數的個數 +1。若有多個相同的數,因輸出最小的排名)。

查詢排名為 x的數。

求 x的前驅(前驅定義為小於 x,且最大的數)。

求 x的後繼(後繼定義為大於 x,且最小的數)。

插入乙個數 x。

輸入7

5 1

5 35 5

1 32 2

3 34 3

輸出 

231

5

什麼是二叉樹?

每個結點最多有兩個子結點,分別稱為左孩子,右孩子,以他們為根的樹稱為左子樹,右子樹。

1

struct

node;

什麼是bst(binary search tree)?

(1)每個元素有唯一的鍵值。這些鍵值能比較大小。

(2)任意乙個結點的鍵值比它的左子樹的任意結點大,右子樹的任意結點小。

所以我們使用中序遍歷就可以得到bst的有序排列。

如圖就是乙個bst。

bst的基本操作有:插入,查詢,刪除。

根據題意,我們只需要實現插入,和查詢的操作。

題目有些東西沒講清楚,比如:

(1)查詢x數的排名時 x可能不在樹上

(2)沒有前驅輸出-0x7fffffff

(3)沒有後繼輸出 0x7fffffff

指標實現的變種bst(有多個相同鍵值,後來插入的相同鍵值被安插在了第乙個相同鍵值的左子樹上)**:

#includeusing

namespace

std;

//使用bst,二叉搜尋樹

struct

node

} *root;

void insert(node*& now,int x)

if (now->v <=x)

insert(now->r, x),now->rsum++;

else

insert(now->l, x), now->lsum++;

}int find_rank(node* now,int x,int

k) int find_num(node* now,int

x) int prev_num(int

x)

else

}returnc;}

int next_num(int

x)

else

}returnc;}

intmain()

}return0;

}

(這個過樣例的時候是可以的,但在提交的時候莫名其妙要把cout然後是陣列實現**。

#include#include

using

namespace

std;

const

int inf=0x7fffffff

;int

cont;

struct

nodetree[

500010

];int

n,opt,xx;

void add(int x,int

v)

if(tree[x].val>v)

}else

}}int queryfr(int x, int val, int

ans)

else

}int queryne(int x, int val, int

ans)

else

}int queryrk(int x,int

rk)int queryval(int x,int

val)

inline

intread()

while(ch>='

0'&&ch<='9'

)

return r*w;

}int

main()

else add(1

,xx);}}

return0;

}

一天一道演算法題 線段樹

題目 模板 線段樹1 rmq問題 range minimum maximum query 和求區間和的問題可以用暴力法做,時間複雜度為o n 2 用在本題會超時,所以我們選擇線段樹做。線段樹是一種用於區間操作的資料結構,用二叉樹構造。如圖。線段樹的每個節點代表了乙個區間。防止超時,用了lazy標記。...

一天一道演算法題 樹狀陣列

題目 模板 樹狀陣列1 樹狀陣列和線段樹差不多,可以處理區間操作,但是處理不了太複雜的區間問題。不過 比線段樹簡潔很多很多!時間複雜度都為o logn 例如,區間 1,8 儲存方式如下 1 tree 1 num 1 001 001 2 tree 2 num 2 num 1 010 010 001 3...

一天一道演算法題 5 24 遞迴

我們每一天都應該比昨天更強一點 觀察下列式子 12 12 1 12 6 2 12 4 3 12 3 4 12 3 2 2 12 2 6 12 2 3 2 12 2 2 3 對於給定的n 計算n公有多少種不同的分解式?1 include 2 using namespace std 34 int cnt...