二叉排序樹的建立、插入、刪除、查詢、4種遍歷 C++完整實現
阿新 • • 發佈:2019-01-09
#include<iostream> #include<string> #include<queue> using namespace std; typedef int KeyType; #define NUM 13 class BinSTree; class BinStreeNode { public: KeyType key; BinStreeNode *lchild; BinStreeNode *rchild; BinStreeNode() { lchild=NULL; rchild=NULL; } }; class BinSTree { public: BinStreeNode *root; BinSTree() { root=NULL; } ~BinSTree() { //delete root; } BinStreeNode *BSTreeSearch(/*BinStreeNode *bt,*/KeyType k,BinStreeNode *&p);//查詢失敗返回NULL,p記錄待插入的父結點 void BSTreeInsert(KeyType k);//bt用引用,插入結點為根結點,需要修改root int BSTreeDelete(KeyType k); void BSTreePreOrder(BinStreeNode *bt); void BSTreeInOrder(BinStreeNode *bt); void BSTreeAfOrder(BinStreeNode *bt); void BSTreeLevelTraverse(BinStreeNode *bt);//層次遍歷 bool IsEmpty() { return root==NULL; } }; /* * 二叉排序樹查詢演算法 * 在根指標為bt的二叉排序樹中查詢元素k的節點,若查詢成功,則返回指向該節點的指標 * 查詢成功時,引數p指向查詢到的結點;查詢失敗時,引數p指向k應插入的父節點 */ BinStreeNode *BinSTree::BSTreeSearch(/*BinStreeNode *bt,*/KeyType k,BinStreeNode *&p) { BinStreeNode *q=NULL; q=root; while(q) { p=q; if(q->key==k) return p; else if(q->key>k) q=q->lchild; else q=q->rchild; } return NULL; } //插入操作 void BinSTree::BSTreeInsert(KeyType k) { BinStreeNode *p=NULL,*q; q=root; if(BSTreeSearch(k,p)==NULL)//查詢失敗時才插入 { BinStreeNode *r=new BinStreeNode; r->key=k; if(q==NULL)//根結點為空 { root=r; return ; } if(p&&k<p->key) p->lchild=r; else if(p&&k>p->key) p->rchild=r; } } //先序遍歷 void BinSTree::BSTreePreOrder(BinStreeNode *bt) { if(bt) { cout<<bt->key<<" "; BSTreePreOrder(bt->lchild); BSTreePreOrder(bt->rchild); } } //中序遍歷 void BinSTree::BSTreeInOrder(BinStreeNode *bt) //時間複雜度O(N); { if(bt) { BSTreeInOrder(bt->lchild); cout<<bt->key<<" "; BSTreeInOrder(bt->rchild); } } //後序遍歷 void BinSTree::BSTreeAfOrder(BinStreeNode *bt) { if(bt) { BSTreeAfOrder(bt->lchild); BSTreeAfOrder(bt->rchild); cout<<bt->key<<" "; } } //層次遍歷 void BinSTree::BSTreeLevelTraverse(BinStreeNode *bt) { queue<BinStreeNode*> q; if(bt) q.push(bt); while(!q.empty()) { cout<<q.front()->key<<" ";//訪問隊頭結點 if(q.front()->lchild) q.push(q.front()->lchild); if(q.front()->rchild) q.push(q.front()->rchild); q.pop(); } cout<<endl; } //二叉排序樹刪除操作,刪除成功返回1,失敗返回0. int BinSTree::BSTreeDelete(KeyType k) { BinStreeNode *f,*p,*q,*s; p=root; f=NULL; //查詢關鍵字為k的結點,同時將此結點的雙親找出來 while(p&&p->key!=k) { f=p; //f記錄父結點 if(p->key>k) p=p->lchild; else p=p->rchild; } if(!p)//找不到待刪除結點時返回 return 0; if(p->lchild==NULL) //待刪除結點的左子樹為空 { if(f==NULL)//待刪除結點為根結點 root=p->rchild; else if(f->lchild==p)//待刪除結點是其雙親結點的左節點 f->lchild=p->rchild; else //待刪除結點是其雙親結點的右結點 f->rchild=p->rchild; delete p; } else //待刪除結點有左子樹 { q=p; s=p->lchild; while(s->rchild) //在待刪除結點的左子樹中查詢最右下結點,即查詢待刪除結點的中序前驅結點 { q=s; s=s->rchild; } if( q == p ) q->lchild = s->lchild; else q->rchild = s->lchild; p->key = s->key; //值替代法刪除節點 delete s; } return 1; } int main() { int a[NUM]={34, 18, 76, 13,12,11, 52, 82, 16, 67, 58, 73, 72 }; BinSTree bst; BinStreeNode *pBt = NULL, *p = NULL, *pT = NULL; for(int i=0;i<NUM;i++) { bst.BSTreeInsert(a[i]); } pT = bst.BSTreeSearch(51, p ); //搜尋排序二叉樹 bst.BSTreeLevelTraverse(bst.root); if(pT) { cout<<pT->key<<endl; } bst.BSTreePreOrder(bst.root); cout << endl; bst.BSTreeDelete(13); //刪除無左孩子的情況 bst.BSTreePreOrder(bst.root); cout << endl; bst.BSTreeDelete( 76 ); //刪除有左孩子的情況 bst.BSTreePreOrder(bst.root); cout << endl; system("pause"); return 0; }
二叉排序樹的建立、插入、刪除、查詢、4種遍歷方式的C++完整實現版