標籤:c語言實現 情況 語句 bis img targe 複製 子節點 它的
?寫在前面
關於二叉樹的基礎知識,請看我的一篇部落格:二叉樹的鏈式儲存
說明:
二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹:
1.若其左子樹不空,則左子樹上所有結點的值均小於它的根結點的值;
2.若其右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;
3.其左、右子樹也分別為二叉排序樹
?二叉尋找樹的建立(插入):
說明:
二叉樹的建立是二叉樹反覆插入節點所構造出來的!
若二叉樹為空白樹,則插入元素作為樹根節點。
若根結點的索引值等於key,則插入失敗;
若key小於根結點的索引值,則插入到根的左子樹上;否則,插入到根的右子樹上
新插入的節點一定是一個葉子節點!
程式碼分析:
void InsertBST(BiStree &Tree,ElemType e){ BiStree T =Tree; //定義執行副本,! BiStree father =NULL; //定義 while (T&&T->data.key!=e.key) { father=T; if(e.key>T->data.key) T=T->Rchild; else T=T->Lchild; } if(T) //跳出迴圈的只有兩種情況,要麼就是T不存在,要麼就是找到了對應元素!T 存在說明,只能是對應元素也存在,那我我們就不用插入了 return; BiSnode *s = (BiSnode*)malloc(sizeof(BiSnode));//能到這裡,說明節點不存在,建立一個節點,並初始化! s->data=e; s->Rchild=s->Lchild=NULL; if(father==NULL) //如果farther不存在,那說明就是沒有執行While語句,也即是樹是空的,因為一旦執行,就不會為NULL! Tree=s; else if(e.key>father->data.key) //到這裡說明Farther存在,那麼剩下的就是往farther左右節點插入元素了 father->Rchild=s; else father->Lchild=s;}?刪除運算
說明:
刪除運算是的基礎是尋找元素,首先要尋找要刪除的元素,如果找到就刪除,找不到就不用刪除了。
尋找部分代碼:
void DelBST(BiStree &Tree,char key){ if(!Tree) //如果節點為空白節點,說明要刪除的元素不可能存在,所以返回就好! return; else //下面是節點存在的分情況判斷: { if(Tree->data.key==key) //如果找到了要刪除的節點! { deleteNode(Tree); //刪除該節點 } else if(Tree->data.key<key) //如果要刪除的節點大於該節點,則往該節點的右子樹方向進行尋找 DelBST(Tree->Rchild,key); else DelBST(Tree->Lchild,key);//如果要刪除的節點小於該節點,則往該節點的左子樹方向進行尋找 }}
到現在我們已經找到元素了 ,要對其刪除,就是要實現deleteNode(Tree);方法!
但是刪除元素的運算是存在多種情況的,我們要分別處理:
★待刪除的結點*p是個葉子結點
★待刪除的結點*p是僅有一個非空子樹
★待刪除的結點*p有兩個非空子樹
如何找出直接前驅:找到要刪除節點的第一個左子樹然後一直向右!
刪除代碼如下:
void deleteNode(BiStree &p){ if(!p->Rchild) //對第一種及第二種情況的處理 { BiSnode * q =p; p=p->Lchild; free(q); } else if(!p->Lchild) //對第一種及第二種情況的處理 { BiSnode * q =p; p=p->Rchild; free(q); } else { BiSnode * q =p; BiSnode * s =p->Lchild; while (s->Rchild) { q=s; s=s->Rchild; } //s指向被刪節點p的前驅 p->data=s->data; if(q!=p) //詳見下兩圖 q->Rchild=s->Lchild; //左圖 else q->Lchild=s->Lchild; //右圖 free(s); }}
?尋找運算:
代碼就不示範了,很簡單哦!
尋找索引值為K的記錄:
若二叉排序樹為空白樹,則尋找失敗,返回;
若根結點的索引值等於key,則尋找成功,返回;
若根結點的索引值大於key,則到根的左子樹上繼續尋找;否則,到根的右子樹上繼續尋找
資料結構:二叉尋找樹(C語言實現)