日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

二叉查找树(二)之 C++的实现

發布時間:2025/3/20 c/c++ 12 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉查找树(二)之 C++的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
二叉查找樹(二)之 C++的實現

?

概要

上一章介紹了"二叉查找樹的相關理論知識,并通過C語言實現了二叉查找樹"。這一章給出二叉查找樹的C++版本。這里不再對樹的相關概念進行介紹,若遇到不明白的概念,可以在上一章查找。

目錄
1.?二叉樹查找樹
2.?二叉查找樹的C++實現
3.?二叉查找樹的C++實現(完整源碼)
4.?二叉查找樹的C++測試程序

轉載請注明出處:http://www.cnblogs.com/skywang12345/p/3576373.html


更多內容:?數據結構與算法系列 目錄?

(01)?二叉查找樹(一)之 圖文解析 和 C語言的實現
(02)?二叉查找樹(二)之 C++的實現

?

二叉查找樹簡介

二叉查找樹(Binary Search Tree),又被稱為二叉搜索樹。
它是特殊的二叉樹:對于二叉樹,假設x為二叉樹中的任意一個結點,x節點包含關鍵字key,節點x的key值記為key[x]。如果y是x的左子樹中的一個結點,則key[y] <= key[x];如果y是x的右子樹的一個結點,則key[y] >= key[x]。那么,這棵樹就是二叉查找樹。如下圖所示:

在二叉查找樹中:
(01) 若任意節點的左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;
(02) 任意節點的右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;
(03) 任意節點的左、右子樹也分別為二叉查找樹。
(04) 沒有鍵值相等的節點(no duplicate nodes)。

?

二叉查找樹的C++實現

1. 節點和二叉查找樹的定義

1.1 二叉查找樹節點

template <class T> class BSTNode{public:T key; // 關鍵字(鍵值)BSTNode *left; // 左孩子BSTNode *right; // 右孩子BSTNode *parent;// 父結點 BSTNode(T value, BSTNode *p, BSTNode *l, BSTNode *r):key(value),parent(),left(l),right(r) {} };

BSTNode是二叉查找樹的節點,它包含二叉查找樹的幾個基本信息:
(01) key -- 它是關鍵字,是用來對二叉查找樹的節點進行排序的。
(02) left -- 它指向當前節點的左孩子。
(03) right -- 它指向當前節點的右孩子。
(04) parent -- 它指向當前節點的父結點。

?

1.2 二叉樹操作

template <class T> class BSTree {private:BSTNode<T> *mRoot; // 根結點public:BSTree();~BSTree();// 前序遍歷"二叉樹"void preOrder();// 中序遍歷"二叉樹"void inOrder();// 后序遍歷"二叉樹"void postOrder();// (遞歸實現)查找"二叉樹"中鍵值為key的節點BSTNode<T>* search(T key);// (非遞歸實現)查找"二叉樹"中鍵值為key的節點BSTNode<T>* iterativeSearch(T key);// 查找最小結點:返回最小結點的鍵值。 T minimum();// 查找最大結點:返回最大結點的鍵值。 T maximum();// 找結點(x)的后繼結點。即,查找"二叉樹中數據值大于該結點"的"最小結點"。BSTNode<T>* successor(BSTNode<T> *x);// 找結點(x)的前驅結點。即,查找"二叉樹中數據值小于該結點"的"最大結點"。BSTNode<T>* predecessor(BSTNode<T> *x);// 將結點(key為節點鍵值)插入到二叉樹中void insert(T key);// 刪除結點(key為節點鍵值)void remove(T key);// 銷毀二叉樹void destroy();// 打印二叉樹void print();private:// 前序遍歷"二叉樹"void preOrder(BSTNode<T>* tree) const;// 中序遍歷"二叉樹"void inOrder(BSTNode<T>* tree) const;// 后序遍歷"二叉樹"void postOrder(BSTNode<T>* tree) const;// (遞歸實現)查找"二叉樹x"中鍵值為key的節點BSTNode<T>* search(BSTNode<T>* x, T key) const;// (非遞歸實現)查找"二叉樹x"中鍵值為key的節點BSTNode<T>* iterativeSearch(BSTNode<T>* x, T key) const;// 查找最小結點:返回tree為根結點的二叉樹的最小結點。BSTNode<T>* minimum(BSTNode<T>* tree);// 查找最大結點:返回tree為根結點的二叉樹的最大結點。BSTNode<T>* maximum(BSTNode<T>* tree);// 將結點(z)插入到二叉樹(tree)中void insert(BSTNode<T>* &tree, BSTNode<T>* z);// 刪除二叉樹(tree)中的結點(z),并返回被刪除的結點BSTNode<T>* remove(BSTNode<T>* &tree, BSTNode<T> *z);// 銷毀二叉樹void destroy(BSTNode<T>* &tree);// 打印二叉樹void print(BSTNode<T>* tree, T key, int direction); };

BSTree是二叉樹。它包含二叉查找樹的根節點和二叉查找樹的操作。二叉查找樹的操作中有許多重載函數,例如insert()函數,其中一個是內部接口,另一個是提供給外部的接口。

?

2 遍歷

這里講解前序遍歷、中序遍歷、后序遍歷3種方式。

2.1 前序遍歷
若二叉樹非空,則執行以下操作:
(01) 訪問根結點;
(02) 先序遍歷左子樹;
(03) 先序遍歷右子樹。

前序遍歷代碼

template <class T> void BSTree<T>::preOrder(BSTNode<T>* tree) const {if(tree != NULL){cout<< tree->key << " " ;preOrder(tree->left);preOrder(tree->right);} }template <class T> void BSTree<T>::preOrder() {preOrder(mRoot); }

?

2.2 中序遍歷

若二叉樹非空,則執行以下操作:
(01) 中序遍歷左子樹;
(02) 訪問根結點;
(03) 中序遍歷右子樹。

中序遍歷代碼

template <class T> void BSTree<T>::inOrder(BSTNode<T>* tree) const {if(tree != NULL){inOrder(tree->left);cout<< tree->key << " " ;inOrder(tree->right);} }template <class T> void BSTree<T>::inOrder() {inOrder(mRoot); }

?

2.3 后序遍歷

若二叉樹非空,則執行以下操作:
(01) 后序遍歷左子樹;
(02) 后序遍歷右子樹;
(03) 訪問根結點。

后序遍歷代碼

template <class T> void BSTree<T>::postOrder(BSTNode<T>* tree) const {if(tree != NULL){postOrder(tree->left);postOrder(tree->right);cout<< tree->key << " " ;} }template <class T> void BSTree<T>::postOrder() {postOrder(mRoot); }

?

?

看看下面這顆樹的各種遍歷方式:

對于上面的二叉樹而言,
(01) 前序遍歷結果:?3 1 2 5 4 6
(02) 中序遍歷結果:?1 2 3 4 5 6?
(03) 后序遍歷結果:?2 1 4 6 5 3

?

3. 查找

遞歸版本的代碼

template <class T> BSTNode<T>* BSTree<T>::search(BSTNode<T>* x, T key) const {if (x==NULL || x->key==key)return x;if (key < x->key)return search(x->left, key);elsereturn search(x->right, key); }template <class T> BSTNode<T>* BSTree<T>::search(T key) {search(mRoot, key); }

非遞歸版本的代碼

template <class T> BSTNode<T>* BSTree<T>::iterativeSearch(BSTNode<T>* x, T key) const {while ((x!=NULL) && (x->key!=key)){if (key < x->key)x = x->left;elsex = x->right;}return x; }template <class T> BSTNode<T>* BSTree<T>::iterativeSearch(T key) {iterativeSearch(mRoot, key); }


4. 最大值和最小值

查找最大值的代碼

template <class T> BSTNode<T>* BSTree<T>::maximum(BSTNode<T>* tree) {if (tree == NULL)return NULL;while(tree->right != NULL)tree = tree->right;return tree; }template <class T> T BSTree<T>::maximum() {BSTNode<T> *p = maximum(mRoot);if (p != NULL)return p->key;return (T)NULL; }

查找最小值的代碼

template <class T> BSTNode<T>* BSTree<T>::minimum(BSTNode<T>* tree) {if (tree == NULL)return NULL;while(tree->left != NULL)tree = tree->left;return tree; }template <class T> T BSTree<T>::minimum() {BSTNode<T> *p = minimum(mRoot);if (p != NULL)return p->key;return (T)NULL; }

?

5. 前驅和后繼

節點的前驅:是該節點的左子樹中的最大節點。
節點的后繼:是該節點的右子樹中的最小節點。

查找前驅節點的代碼

/* * 找結點(x)的前驅結點。即,查找"二叉樹中數據值小于該結點"的"最大結點"。*/ template <class T> BSTNode<T>* BSTree<T>::predecessor(BSTNode<T> *x) {// 如果x存在左孩子,則"x的前驅結點"為 "以其左孩子為根的子樹的最大結點"。if (x->left != NULL)return maximum(x->left);// 如果x沒有左孩子。則x有以下兩種可能:// (01) x是"一個右孩子",則"x的前驅結點"為 "它的父結點"。// (01) x是"一個左孩子",則查找"x的最低的父結點,并且該父結點要具有右孩子",找到的這個"最低的父結點"就是"x的前驅結點"。BSTNode<T>* y = x->parent;while ((y!=NULL) && (x==y->left)){x = y;y = y->parent;}return y; }

查找后繼節點的代碼

/* * 找結點(x)的后繼結點。即,查找"二叉樹中數據值大于該結點"的"最小結點"。*/ template <class T> BSTNode<T>* BSTree<T>::successor(BSTNode<T> *x) {// 如果x存在右孩子,則"x的后繼結點"為 "以其右孩子為根的子樹的最小結點"。if (x->right != NULL)return minimum(x->right);// 如果x沒有右孩子。則x有以下兩種可能:// (01) x是"一個左孩子",則"x的后繼結點"為 "它的父結點"。// (02) x是"一個右孩子",則查找"x的最低的父結點,并且該父結點要具有左孩子",找到的這個"最低的父結點"就是"x的后繼結點"。BSTNode<T>* y = x->parent;while ((y!=NULL) && (x==y->right)){x = y;y = y->parent;}return y; }


6. 插入

插入節點的代碼

/* * 將結點插入到二叉樹中** 參數說明:* tree 二叉樹的根結點* z 插入的結點*/ template <class T> void BSTree<T>::insert(BSTNode<T>* &tree, BSTNode<T>* z) {BSTNode<T> *y = NULL;BSTNode<T> *x = tree;// 查找z的插入位置while (x != NULL){y = x;if (z->key < x->key)x = x->left;elsex = x->right;}z->parent = y;if (y==NULL)tree = z;else if (z->key < y->key)y->left = z;elsey->right = z; }/* * 將結點(key為節點鍵值)插入到二叉樹中** 參數說明:* tree 二叉樹的根結點* key 插入結點的鍵值*/ template <class T> void BSTree<T>::insert(T key) {BSTNode<T> *z=NULL;// 如果新建結點失敗,則返回。if ((z=new BSTNode<T>(key,NULL,NULL,NULL)) == NULL)return ;insert(mRoot, z); }

注:本文實現的二叉查找樹是允許插入相同鍵值的節點的。若想禁止二叉查找樹中插入相同鍵值的節點,可以參考"二叉查找樹(一)之 圖文解析 和 C語言的實現"中的插入函數進行修改。

?

7. 刪除

刪除節點的代碼

/* * 刪除結點(z),并返回被刪除的結點** 參數說明:* tree 二叉樹的根結點* z 刪除的結點*/ template <class T> BSTNode<T>* BSTree<T>::remove(BSTNode<T>* &tree, BSTNode<T> *z) {BSTNode<T> *x=NULL;BSTNode<T> *y=NULL;if ((z->left == NULL) || (z->right == NULL) )y = z;elsey = successor(z);if (y->left != NULL)x = y->left;elsex = y->right;if (x != NULL)x->parent = y->parent;if (y->parent == NULL)tree = x;else if (y == y->parent->left)y->parent->left = x;elsey->parent->right = x;if (y != z) z->key = y->key;return y; }/* * 刪除結點(z),并返回被刪除的結點** 參數說明:* tree 二叉樹的根結點* z 刪除的結點*/ template <class T> void BSTree<T>::remove(T key) {BSTNode<T> *z, *node; if ((z = search(mRoot, key)) != NULL)if ( (node = remove(mRoot, z)) != NULL)delete node; }

?

8. 打印

打印二叉查找樹的代碼

/** 打印"二叉查找樹"** key -- 節點的鍵值 * direction -- 0,表示該節點是根節點;* -1,表示該節點是它的父結點的左孩子;* 1,表示該節點是它的父結點的右孩子。*/ template <class T> void BSTree<T>::print(BSTNode<T>* tree, T key, int direction) {if(tree != NULL){if(direction==0) // tree是根節點cout << setw(2) << tree->key << " is root" << endl;else // tree是分支節點cout << setw(2) << tree->key << " is " << setw(2) << key << "'s " << setw(12) << (direction==1?"right child" : "left child") << endl;print(tree->left, tree->key, -1);print(tree->right,tree->key, 1);} }template <class T> void BSTree<T>::print() {if (mRoot != NULL)print(mRoot, mRoot->key, 0); }

?

9. 銷毀

銷毀二叉查找樹的代碼

/** 銷毀二叉樹*/ template <class T> void BSTree<T>::destroy(BSTNode<T>* &tree) {if (tree==NULL)return ;if (tree->left != NULL)return destroy(tree->left);if (tree->right != NULL)return destroy(tree->right);delete tree;tree=NULL; }template <class T> void BSTree<T>::destroy() {destroy(mRoot); }

?

二叉查找樹的C++實現(完整源碼)

二叉查找樹的C++實現文件(BSTree.h)

?View Code

二叉查找樹的C++測試程序(BSTreeTest.cpp)

?View Code

關于二叉查找樹的C++實現有兩點需要補充說明的:
第1點:采用了STL模板。因此,二叉查找樹支持任意數據類型。
第2點:將二叉查找樹的"聲明"和"實現"都位于BSTree.h中。這是因為,在二叉查找樹的實現采用了模板;而C++編譯器不支持對模板的分離式編譯!

?

二叉查找樹的C++測試程序

上面的BSTreeTest.c是二叉查找樹樹的測試程序,運行結果如下:

== 依次添加: 1 5 4 3 2 6 == 前序遍歷: 1 5 4 3 2 6 == 中序遍歷: 1 2 3 4 5 6 == 后序遍歷: 2 3 4 6 5 1 == 最小值: 1 == 最大值: 6 == 樹的詳細信息: 1 is root5 is 1's right child4 is 5's left child3 is 4's left child2 is 3's left child6 is 5's right child== 刪除根節點: 3 == 中序遍歷: 1 2 4 5 6

?

下面對測試程序的流程進行分析!

(01) 新建"二叉查找樹"root。


(02) 向二叉查找樹中依次插入1,5,4,3,2,6 。如下圖所示:

?

(03) 遍歷和查找
插入1,5,4,3,2,6之后,得到的二叉查找樹如下:

前序遍歷結果:?1 5 4 3 2 6?
中序遍歷結果:?1 2 3 4 5 6?
后序遍歷結果:?2 3 4 6 5 1?
最小值是1,而最大值是6。

?

(04) 刪除節點4。如下圖所示:

?

(05) 重新遍歷該二叉查找樹。
中序遍歷結果:?1 2 4 5 6

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的二叉查找树(二)之 C++的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 波多野结衣视频一区 | 国产精品xxx| 亚洲色图欧美另类 | 精品嫩模一区二区三区 | 国产美女被遭强高潮免费网站 | 黄瓜视频在线免费观看 | 亚洲av综合一区二区 | 国产传媒av| 国产剧情av引诱维修工 | 91福利一区 | 日本美女性高潮 | 国产女主播喷水视频在线观看 | 日韩欧美在线不卡 | 日韩少妇一区二区 | 亚洲成人精品视频 | 影音先锋中文字幕一区二区 | 欧美一区在线观看视频 | 青青五月天 | 日本毛片视频 | 亚洲av无码一区二区乱子伦as | 影音av在线 | 欧美三日本三级少妇99 | 亚洲狼人综合 | 久久国产激情视频 | 欧美www视频 | 久久久精品免费视频 | 亚洲av人无码激艳猛片服务器 | 私密视频在线观看 | 中文字幕在线网 | 亚洲一区天堂 | 嫩草嫩草嫩草 | 大肉大捧一进一出好爽 | 国产日产欧美一区二区三区 | 久久av影院 | 96国产精品| 成人精品三级av在线看 | 日本乱偷人妻中文字幕在线 | 日本久久久久 | 久久偷看各类女兵18女厕嘘嘘 | 97视频免费在线 | av日日夜夜 | 香蕉av一区 | 一卡二卡三卡在线视频 | 国产精品视频成人 | 黄色福利社 | 99ri国产在线 | 国产精品成人久久电影 | 一本色道久久综合熟妇 | 欧美特黄一级大片 | 亚洲品质自拍视频网站 | 日日夜夜艹| 强开乳罩摸双乳吃奶羞羞www | 久久偷看各类女兵18女厕嘘嘘 | 国产一区二区三区久久 | av中亚| 国产乱国产乱老熟300部视频 | 亚洲天堂男人网 | xxxwww在线观看 | 91精品婷婷国产综合久久竹菊 | 四虎影院一区 | 高级家教课程在线观看 | 一区二区三区四区视频在线观看 | 另类小说婷婷 | 毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 97超碰站| 黄色性生活一级片 | 在线观看免费高清在线观看 | 91大神一区二区 | 夜夜嗨av一区二区 | 我和岳m愉情xxxⅹ视频 | 亚洲自拍偷拍一区二区 | avtt2015| 国产精品乱码一区 | 欧美激情国产一区 | 性网站在线观看 | 精品国产免费无码久久久 | 99热在线观看免费 | 五月激情在线观看 | 国产高潮久久 | 精品少妇| 日韩人妻精品中文字幕 | 久久精品国产欧美亚洲人人爽 | 国产中文字幕三区 | 天堂va蜜桃一区 | 免费看黄色片视频 | 国产精品999久久久 在线青草 | 亚洲熟女综合色一区二区三区 | 免费黄色片子 | 黄色在线视频网址 | av超碰在线观看 | 亚洲黄色自拍 | 青草青草久热 | 老司机免费在线视频 | 女人洗澡一级特黄毛片 | 亚洲精品毛片av | 午夜精品福利在线观看 | 日本一区二区视频在线观看 | 日本三级吹潮 | 久久99久久99精品 |