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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

二叉搜索树的查询操作《算法导论》12.2

發布時間:2025/3/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 二叉搜索树的查询操作《算法导论》12.2 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 我們可以在O(h)時間內完成二叉搜索樹的查找、最大值、最小值、給定節點的前驅、后繼操作,h代表樹的高度。下面是用C++實現的《算法導論》12.2節偽代碼,附習題解答。
#include <iostream> #include <queue> #include <stack> using namespace std;struct Node {int key;Node* parent;Node* left;Node* right;Node(int k) :key(k),parent(nullptr),left(nullptr),right(nullptr){}Node(){} };//insert a node to the tree rooted at a giver node void insert(Node* pRoot, Node* pAdd) {Node *pParent = pRoot, *pTmpParent;bool bLeft;while(true){bLeft = (pAdd->key < pParent->key) ? true : false;pTmpParent = bLeft ? pParent->left : pParent->right;if(nullptr != pTmpParent){pParent = pTmpParent;continue;}pAdd->parent = pParent;if(bLeft)pParent->left = pAdd;elsepParent->right = pAdd;break;} }/*create the tree, we assume all keys to be distinct* 15* 6 18* 3 7 17 20* 2 4 13* 9*/ Node* build() {Node* pRoot = new Node(15);insert(pRoot, new Node(6));insert(pRoot, new Node(3));insert(pRoot, new Node(2));insert(pRoot, new Node(4));insert(pRoot, new Node(7));insert(pRoot, new Node(13));insert(pRoot, new Node(9));insert(pRoot, new Node(18));insert(pRoot, new Node(17));insert(pRoot, new Node(20));return pRoot; }//destroy the tree void destroy(Node* pRoot) {std::queue<Node*> q;q.push(pRoot);Node* p;while(!q.empty()){p = q.front();q.pop();if(!p)continue;q.push(p->left);q.push(p->right);delete p;} }//inorder tree walk void walk(Node* pRoot) {stack<Node*> stk;stk.push(pRoot);while(true){Node* pCurrent = stk.top();if(pCurrent){stk.push(pCurrent->left);continue;}stk.pop();if(stk.empty())break;pCurrent = stk.top();cout << pCurrent->key << "\t";stk.pop();stk.push(pCurrent->right);} }//recursive search Node* search(Node* pRoot, int key) {if(!pRoot)return nullptr;if(key == pRoot->key)return pRoot;if(key < pRoot->key)return search(pRoot->left, key);elsereturn search(pRoot->right, key); }//nonrecursive search Node* search1(Node* pRoot, int key) {while(pRoot && key != pRoot->key){if(key < pRoot->key)pRoot = pRoot->left;elsepRoot = pRoot->right;}return pRoot; }//returns a pointer to the minimum element in the subtree rooted at a given node x, which we assume to be not null Node* minimum(Node* pRoot) {cout << "minimum in the tree rooted at Node " << pRoot->key << "\tis: ";while(pRoot->left != nullptr)pRoot = pRoot->left;cout << pRoot->key << endl;return pRoot; }Node* minimum_recursive(Node* pRoot) {if(nullptr == pRoot->left)return pRoot;return minimum_recursive(pRoot->left); }//returns a pointer to the maximum element in the subtree rooted at a given node x, which we assume to be not null Node* maximum(Node* pRoot) {cout << "manimum in the tree rooted at Node " << pRoot->key << "\tis: ";while(pRoot->right != nullptr)pRoot = pRoot->right;cout << pRoot->key << endl;return pRoot; } Node* maximum_recursive(Node* pRoot) {if(nullptr == pRoot->right)return pRoot;return maximum_recursive(pRoot->right); }//returns the node with the largest key smaller than p->key in the sorted order Node* predecessor(Node* p) {if(p->left)return maximum(p->left);Node* pParent = p->parent;while(pParent && p == pParent->left){p = pParent;pParent = p->parent;}return pParent; }//returns the node with the smallest key greater than p->key in the sorted order Node* successor(Node* p) {if(p->right)return minimum(p->right);Node* pParent = p->parent;while(pParent && pParent->right == p){p = pParent;pParent = p->parent;}return pParent; }void testBinarySearchTree() {Node* pRoot = build();walk(pRoot);cout << endl;{cout << search(pRoot, 9)->key << endl;cout << search(pRoot, 13)->key << endl;cout << search1(pRoot, 17)->key << endl;cout << search1(pRoot, 4)->key << endl;}{minimum(pRoot);minimum(pRoot->right);minimum(pRoot->left->right);cout << minimum_recursive(pRoot)->key << endl;cout << minimum_recursive(pRoot->right)->key << endl;cout << minimum_recursive(pRoot->left->right)->key << endl;}{maximum(pRoot);maximum(pRoot->right->right);maximum(pRoot->left);cout << maximum_recursive(pRoot)->key << endl;cout << maximum_recursive(pRoot->right->right)->key << endl;cout << maximum_recursive(pRoot->left)->key << endl;}{cout << "the predecessor of " << pRoot->key << "\tis: "<< predecessor(pRoot)->key << endl;cout << "the predecessor of " << pRoot->right->left->key << "\tis: "<< predecessor(pRoot->right->left)->key<< endl;cout << "the predecessor of " << pRoot->left->right->key << "\tis: "<< predecessor(pRoot->left->right)->key << endl;}{cout << "the successor of " << pRoot->key << "\tis: "<< successor(pRoot)->key << endl;cout << "the successor of " << pRoot->right->left->key << "\tis: "<< successor(pRoot->right->left)->key<< endl;cout << "the successor of " << pRoot->left->right->right->key << "\tis: "<< successor(pRoot->left->right->right)->key << endl;}destroy(pRoot); }/*output: 2 3 4 6 7 9 13 15 17 18 20 9 13 17 4 minimum in the tree rooted at Node 15 is: 2 minimum in the tree rooted at Node 18 is: 17 minimum in the tree rooted at Node 7 is: 7 2 17 7 maximum in the tree rooted at Node 15 is: 20 maximum in the tree rooted at Node 20 is: 20 maximum in the tree rooted at Node 6 is: 13 20 20 13 maximum in the tree rooted at Node 6 is: 13 the predecessor of 15 is: 13 the predecessor of 17 is: 15 the predecessor of 7 is: 6 minimum in the tree rooted at Node 18 is: 17 the successor of 15 is: 17 the successor of 17 is: 18 the successor of 13 is: 15 */
  • 習題
    12.2-1 c “911 240”說明240是911的左子樹,這棵子樹上不可能出現大于911的912

    12.2-2 見maximum_recursive() minimum_recursive()

    12.2-3 見 predecessor()

    12.2-4 反例: 在下面這棵樹上查找關鍵字5,集合A{3},B{2,4,5} A中的元素3 < b中的元素2 不成立。
    正確的結論應該是:對集合A中任意元素a有a < k,對集合C中任意元素c有c > k。

    12.2-5 如果節點A的前驅P有左孩子K,那么A的前驅就應該是K而不是P了,所以前驅沒有左孩子。

    12.2-7 簡單來講,調用一次minimum和n-1次successor行走的路徑和inorder_tree_walk是一樣的,都是每個節點被訪問兩次,每次從一個節點到下一個節點的過程都是O(1)-time的,所以n個節點總共耗時O(n)-time。

    12.2-8 受7題啟發,successor和tree-walk的共同點是最終走過的路途長度和遍歷過的節點樹是相同的,不同之處在于路程和已遍歷節點數兩者的遞增速度有差異。tree-walk算法中兩者是始終勻速的,互不相欠;successor算法中路程有時稍塊,提前預支了一些尚未遍歷節點的路程份額,而這個預支長度最多是h,所以O(n+h)

    12.2-9 按照predecessor和successor的算法,如果x是y的左孩子,y就是x的successor,如果x是y的右孩子,y就是x的predecessor

2\4/ \3 5

轉載于:https://www.cnblogs.com/meixiaogua/p/9877203.html

與50位技術專家面對面20年技術見證,附贈技術全景圖

總結

以上是生活随笔為你收集整理的二叉搜索树的查询操作《算法导论》12.2的全部內容,希望文章能夠幫你解決所遇到的問題。

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