標籤:二叉尋找樹 資料結構
C++二叉尋找樹:Binary Search tree
二叉尋找樹預設左子樹的值都比根節點小,右子樹都比根節點大,這個定義排除了樹中存在值相同節點的可能性。這便是二叉尋找樹稱為一個用關鍵值KEY快速尋找的工具。
二叉樹類:
class bst{ struct Node { T data; Node* L; Node* R; Node(const T& d):data(d),L(),R(){} Node(const T& d,Node* L,Node* R):data(d),L(L),R(R){} }; typedef Node* tree; Node* rp;//指向根節點指標 int n;//記錄節點個數};
1.插入一個節點; void(tree& t,Node* p)//在一棵樹樹中插入一個節點
if(空樹),作為根結點插入
if(大於根節點值),插入右子樹
else 插入左子樹
void myinsert(tree& t,Node* p)//在一棵樹中插入一個節點 { if(t == NULL) t = p; else if(p->data < t->data) myinsert(t->L,p); else myinsert(t->R,p); }
2.尋找一個節點: tree& (tree& t,const T& d)//在一棵樹中尋找節點d,返回一個指向這個節點的指標。
if(t==NULL) return t;
if(t->data==d) return t;
if(d < t->data) return 左子樹中尋找
else return右子樹尋找
tree& myfind(tree& t,const T& d)//返回以d為根節點的子樹的根指標 { if(t==NULL) return t; else if(d==t->data) return t;//沒找到 else if(d<t->data) return myfind(t->L,d);//return 一定要帶上 else return myfind(t->R,d); } void tr
3.刪除一個節點:void dele(tree& t,const T& d)
特殊:
葉子節點----->直接delete
單子節點---->讓父節點指向子節點,delete
雙子節點---->左右子樹合并
1.找到這個節點,即返回指向這個節點的指標pn
2.備份一份指標p=pn
3.左右子樹合并(左子樹插入到右子樹 或者 右子樹插入到左子樹)
4.Delete 節點
5.節點數-1
bool dele(const T& d){//返回那個節點的根指標,另存一份 //左右子樹合并,根指標指向右子樹,釋放節點 tree& t = myfind(d); if(t == NULL) return false; Node* p = t; if(t->L!=NULL) myinsert(t->R,t->L); t = t->R; delete p; --n; return true; }
4修改一個節點; void(const T& olddata,const T& newdata)
1,刪掉這個節點
2.插入一個節點
void update(const T& olddata,const T& newdata) { dele(olddata); myinsert(newdata); }
5.遍曆二叉樹 //中根遍曆
遍曆左子樹
遍曆根節點
遍曆右子樹
void travel(const tree& t)const { if(t != NULL) { travel(t->L); cout << t->data <<' '; travel(t->R); } }
6.清空一棵樹
先清左子樹
在清右子樹
delete根節點
void clean(tree& t)//清空一棵樹 { if(t!=NULL) { clean(t->L); clean(t->R); delete t;t=NULL; } }
7.求樹的深度
int high(tree& t)const//求一棵樹的高度 { if(t == NULL) return 0; int lh=high(t->L); int rh=high(t->R); return 1+std::max(lh,rh); }
8.二叉樹的層次遍曆
1.如果是空樹,over
2.建立隊列,根節點進隊
3 只要隊列不為空白,
3.1 出隊一個元素
3.2訪問其中資料
3.3左右非空子樹入隊
void prin(tree& t) { if(!t) return; deque<tree> di; di.push_back(t); while(!di.empty()) { tree& t=di.front(); cout << t->data << ' '; if(t->L) di.push_back(t->L); if(t->R) di.push_back(t->R); } }
加分行符號,每層遍曆加一個換行
1.如果是空樹,over
2.建立隊列,根節點進隊,NULL進隊
3 只要隊列size>1,
3.1 出隊一個元素
3.2如果是NULL,換行,NULL進隊尾。continue
3.2訪問其中資料
3.3左右非空子樹入隊
void print(tree& t ) { if(t==NULL) return; deque<tree> di;//建立隊列 di.push_back(t);//根節點入隊 di.push_back(NULL); while(di.size()!=1)//只要非空 { tree& t=di.front();//取出一個元素 if(t==NULL) { cout << endl; di.pop_front(); di.push_back(NULL); continue; } cout << t->data << ' ';//訪問資料 di.pop_front(); if(t->L) di.push_back(t->L);//左右子樹非空節點入隊 if(t->R) di.push_back(t->R); } }
C++資料結構====二叉尋找樹