您好,登錄后才能下訂單哦!
小編給大家分享一下如何實現二叉查找樹,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
二叉查找樹又叫二叉排序樹,其特點有:
對于每一棵子樹,若左子樹不為NULL,則左子樹所有節點都小于它的根結點值。
對于每一棵子樹,若右子樹不為NULL,則左子樹所有節點都大于它的根結點值。
沒有鍵值相等的結點。
完成二叉查找樹的基本操作有:
插入結點。
查找結點。
查找最小關鍵字:根據二叉查找樹的特點,應該是最左邊的結點
查找最大關鍵字:根據二叉查找樹的特點,應該是最右邊的結點
刪除結點。
以上操作中,難點在與插入和刪除。分別說下其主要思想:
插入:根據插入數據與結點的比較,找尋它的插入位置,若比結點值大,則往結點的右子樹繼續尋找,直到其右孩子為空,將新結點作為其右孩子;若比結點值小,則往結點的左子樹繼續尋找,直到其左孩子為空,將新結點作為其左孩子。
刪除:設要查找的結點為d
若d有左子樹,則用d的左孩子取代它,找到其左子樹的最右邊的結點r,把f的右孩子作為r的右子樹。
若d無左子樹,則直接用它的右孩子取代它。
但執行刪除操作時要注意要刪除的結點是否是幾個特殊的結點:空結點、根結點、葉子節點。
代碼示例:
//插入結點 //查找元素 //查找最小關鍵字 //查找最大關鍵字 //刪除節點 #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* lchild; struct Node* rchild; struct Node* parent; }Node; //往二叉查找樹中插入結點 //插入的話,可能要改變根結點的地址,所以傳的是二級指針 void insert_node(Node** root,int _data) { Node* newnode=(Node*)malloc(1*sizeof(Node)); newnode->data=_data; newnode->lchild=NULL; newnode->rchild=NULL; newnode->parent=NULL; if(*root==NULL) { *root=newnode; return ; } if((*root)->lchild==NULL && _data < (*root)->data) { (*root)->lchild=newnode; newnode->parent=*root; return ; } if((*root)->rchild==NULL && _data > (*root)->data) { (*root)->rchild=newnode; newnode->parent=*root; return ; } if( _data < (*root)->data ) { insert_node(&(*root)->lchild,_data); } else { if( _data > (*root)->data) { insert_node(&(*root)->rchild,_data); } else { return ; } } } //輸出節點元素 void print_tree(Node* root) { if(root==NULL) return ; printf("%d\t",root->data); print_tree(root->lchild); print_tree(root->rchild); } //查找元素,找到返回關鍵字的結點指針,沒找到返回NULL Node* find_node(Node* root,int _data) { if(root==NULL || ( _data == root->data)) { return root; } if( _data < root->data ) { return find_node(root->lchild,_data); } if(_data > root->data) { return find_node(root->rchild,_data); } } //查找最小關鍵字,空樹時返回NULL Node* search_min(Node* root) { if(root==NULL) { return NULL; } if(root->lchild==NULL) { return root; } search_min(root->lchild); } //查找最大關鍵字 Node* search_max(Node* root) { if(root==NULL) { return NULL; } if(root->rchild==NULL) { return root; } search_max(root->rchild); } //根據關鍵字刪除某個結點,刪除成功返回1,否則返回0 如果把根結點刪掉,那么要改變根結點的地址,所以傳二級指針 /*思想: 1。若p有左子樹,p的左孩子取代它;找到其左子樹的最右邊的葉子結點r,把p的右子樹作為r的右子樹。 2。若p沒有左子樹,直接用p的右孩子取代它。 */ void delete_node(Node** root,int _data) { if(root==NULL) return ; Node* dnode=find_node(*root,_data); if(dnode==NULL) { return ; } if(dnode->lchild==NULL && dnode->rchild==NULL && dnode!=*root) { if(dnode->parent->lchild==dnode) { dnode->parent->lchild=NULL; } if(dnode->parent->rchild==dnode) { dnode->parent->rchild=NULL; } free(dnode); dnode=NULL; return ; } //如沒有左子樹 if(dnode->lchild==NULL) { //若這個節點是根節點 if(dnode==*root) { *root=(*root)->rchild; (*root)->parent=NULL; free(dnode); return ; } //若這個節點是父節點的左孩子 if(dnode->parent->lchild==dnode) { dnode->parent->lchild=dnode->rchild; dnode->rchild->parent=dnode->parent; free(dnode); return ; } //若這個節點是父節點的右孩子 if(dnode->parent->rchild==dnode) { dnode->parent->rchild=dnode->rchild; dnode->rchild->parent=dnode->parent; free(dnode); return ; } } if(dnode->lchild!=NULL) { //找到其左子樹的最右邊的葉子結點r,把p的右子樹作為r的右子樹。 Node* r=dnode->lchild; while(r->rchild!=NULL) { r=r->rchild; } r->rchild=dnode->rchild; dnode->rchild->parent=r->rchild; //用dnode的左節點來取代ta if(dnode==*root) { *root=dnode->lchild; (*root)->parent=NULL; } else { if(dnode->parent->lchild==dnode) { dnode->parent->lchild=dnode->lchild; dnode->lchild->parent=dnode->parent; } if(dnode->parent->rchild==dnode) { dnode->parent->rchild=dnode->lchild; dnode->lchild->parent=dnode->parent; } } free(dnode); dnode=NULL; } } int main(int argc, char const *argv[]) { Node* root=NULL; insert_node(&root,15); insert_node(&root,6); insert_node(&root,18); insert_node(&root,3); insert_node(&root,7); insert_node(&root,17); insert_node(&root,20); print_tree(root); printf("\n"); Node* f=find_node(root,6); if(f!=NULL) { printf("%d\n",f->parent->data); } delete_node(&root,3); print_tree(root); printf("\n"); return 0; }
以上是“如何實現二叉查找樹”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。