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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

数据结构树之二分查找树

發布時間:2025/5/22 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构树之二分查找树 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

二叉查找樹(Binary Search Tree),也稱有序二叉樹(ordered binary tree),排序二叉樹(sorted binary tree),是指一棵空樹或者具有下列性質的二叉樹:

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

      二叉查找樹本質上是一種二叉樹,所以上章講的二叉樹的性質他都有。

    二叉查找樹的思想:

      二叉排序樹的查找過程和次優二叉樹類似,通常采取二叉鏈表作為二叉排序樹的存儲結構。中序遍歷二叉排序樹可得到一個關鍵字的有序序列,一個無序序列可以通過構造一棵二叉排序樹變成一個有序序列,構造樹的過程即為對無序序列進行排序的過程。每次插入的新的結點都是二叉排序樹上新的葉子結點,在進行插入操作時,不必移動其它結點,只需改動某個結點的指針,由空變為非空即可。搜索,插入,刪除的復雜度等于樹高,O(log(n)).

    二叉查找樹的操作:

      /*二叉樹的鏈式定義*/

    1 #define DataType int 2 //二叉樹的前序遍歷 3 typedef struct BiTNode //二元查找樹的節點 4 { 5 DataType m_Value; 6 BiTNode *m_pLeft; 7 BiTNode *m_pRight; 8 }BiTNode;

      //創建二元查找樹,相當于一個個的插入

    1 void addBSTreeNode(BiTNode *&pCurrent,DataType value) 2 { 3 if(NULL == pCurrent) //如果是空的話就創建節點 4 { 5 BiTNode *pBSTree = new BiTNode(); 6 pBSTree->m_pLeft = NULL; 7 pBSTree->m_pRight = NULL; 8 pBSTree->m_Value = value; 9 pCurrent = pBSTree; 10 } 11 else 12 { 13 if(pCurrent->m_Value > value) 14 { 15 addBSTreeNode(pCurrent->m_pLeft,value); 16 } 17 else if(pCurrent->m_Value < value) 18 { 19 addBSTreeNode(pCurrent->m_pRight,value); 20 } 21 else 22 { 23 cout << "重復插入"; 24 } 25 } 26 }

      //二分查找樹的搜索,時間復雜度O(logn)

    1 BiTNode * searchBSTreeNode(BiTNode *pCurrent,DataType value) 2 { 3 if(pCurrent == NULL || pCurrent->m_Value == value) 4 { 5 return pCurrent; 6 } 7 if(pCurrent->m_Value > value) 8 { 9 return searchBSTreeNode(pCurrent->m_pLeft,value); 10 } 11 else 12 { 13 return searchBSTreeNode(pCurrent->m_pRight,value); 14 } 15 }

      //返回二叉查找樹中的最小值

    1 BiTNode * getMinValueFromBSTree(BiTNode *pCurrent) 2 { 3 while(pCurrent->m_pLeft) 4 pCurrent = pCurrent->m_pLeft; 5 return pCurrent; 6 }

      //返回二叉查找樹中的最大值

    1 BiTNode * getMaxValueFromBSTree(BiTNode *pCurrent) 2 { 3 while(pCurrent->m_pRight) 4 pCurrent = pCurrent->m_pRight; 5 return pCurrent; 6 }

      //返回二叉查找樹中的一個節點的后繼結點

    1 BiTNode * getSuccessorNode(BiTNode *pCurrent,BiTNode *x) 2 { 3 if(!x||!pCurrent) 4 return NULL; 5 //如果x節點的右子樹不為空,那么后繼結點一定是右子樹的最左結點 6 if(x->m_pRight) 7 return getMinValueFromBSTree(x->m_pRight); 8 //如果是空節點 9 while(pCurrent) 10 { 11 if(x->m_Value < pCurrent->m_Value) //如果比正在檢查的節點小, 12 if(getMaxValueFromBSTree(pCurrent->m_pLeft)->m_Value == x->m_Value) //根節點只有可能是他左子樹的最大節點的后繼結點 13 return pCurrent; 14 else 15 pCurrent = pCurrent->m_pLeft; 16 else 17 pCurrent = pCurrent->m_pRight; 18 } 19 return pCurrent; 20 }

    //返回二叉查找樹中的一個節點的前驅結點

    1 BiTNode * getPredecessorNode(BiTNode *pCurrent,BiTNode *x) 2 { 3 if(!x||!pCurrent) 4 return NULL; 5 //如果x節點的左子樹不為空,那么后繼結點一定是左子樹的最右結點 6 if(x->m_pLeft) 7 return getMaxValueFromBSTree(x->m_pLeft); 8 //如果是空節點 9 while(pCurrent) 10 { 11 if(x->m_Value > pCurrent->m_Value) //如果比正在檢查的節點小, 12 if(getMinValueFromBSTree(pCurrent->m_pRight)->m_Value == x->m_Value) //根節點只有可能是他右子樹的最小結點的前驅結點 13 return pCurrent; 14 else 15 pCurrent = pCurrent->m_pRight; 16 else 17 pCurrent = pCurrent->m_pLeft; 18 } 19 return pCurrent; 20 }

      //返回一個結點的雙親結點

    1 BiTNode * getParentsNode(BiTNode *pCurrent,BiTNode * x) 2 { 3 if(!pCurrent || pCurrent == x ||!x) //根為空或者就是根節點,則無父節點 4 return NULL; 5 while(pCurrent) 6 { 7 if(pCurrent->m_pLeft == x || pCurrent->m_pRight == x) 8 return pCurrent; 9 if(x->m_Value < pCurrent->m_Value) 10 pCurrent = pCurrent->m_pLeft; 11 else 12 pCurrent = pCurrent->m_pRight; 13 } 14 return NULL; 15 }

      //刪除二叉查找樹中一個值為指定值的結點---這個有點長,主要是有些重復的操作可以封裝到函數中去,我沒有!

    1 void deleteNodeFromBSTreeNode(BiTNode *&pCurrent,DataType value) 2 { 3 if(!pCurrent) 4 return; 5 BiTNode *fitNode = searchBSTreeNode(pCurrent,value); //找到要刪除的結點 6 if(!fitNode) //是NULL,直接返回。沒找到要刪除的結點 7 return ; 8 BiTNode *parents = getParentsNode(pCurrent,fitNode),*temp = NULL; //得到要刪除結點的父親結點 9 if(!fitNode->m_pLeft) //如果左結點為空 10 { 11 if(parents) 12 { 13 if(fitNode == parents->m_pLeft) //如果是父結點的左結點 14 { 15 parents->m_pLeft = fitNode->m_pRight; 16 } 17 else 18 { 19 parents->m_pRight = fitNode->m_pRight; 20 } 21 } 22 else //沒有父結點,那要刪除的就是根節點 23 { 24 pCurrent = fitNode->m_pRight; 25 } 26 } 27 else if(!fitNode->m_pRight) //如果右結點為空 28 { 29 if(parents) 30 { 31 if(fitNode == parents->m_pLeft) //如果是父結點的左結點 32 { 33 parents->m_pLeft = fitNode->m_pLeft; 34 } 35 else 36 { 37 parents->m_pRight = fitNode->m_pLeft; 38 } 39 } 40 else //沒有父結點,那要刪除的就是根節點 41 { 42 pCurrent = fitNode->m_pLeft; 43 } 44 } 45 else //左右孩子都不為空 46 { 47 //找到右子樹中左邊的的結點---即右子樹最小值結點 48 temp = getMinValueFromBSTree(fitNode->m_pRight); 49 if(fitNode->m_pRight != temp) 50 { 51 BiTNode *parents1 = getParentsNode(pCurrent,temp); 52 if(parents1) 53 { 54 //肯定是在父結點的左結點上 55 parents1->m_pLeft = temp->m_pRight; 56 } 57 else 58 { 59 //不可能沒有父結點了 60 } 61 temp->m_pRight = fitNode->m_pRight; 62 temp->m_pLeft = fitNode->m_pLeft; 63 if(parents) 64 { 65 if(parents->m_pLeft == fitNode) 66 { 67 parents->m_pLeft = temp; 68 } 69 else 70 { 71 parents->m_pRight = temp; 72 } 73 } 74 else 75 { 76 pCurrent = temp; 77 } 78 } 79 else 80 { 81 if(parents) 82 { 83 if(parents->m_pLeft == fitNode) 84 { 85 parents->m_pLeft = temp; 86 temp ->m_pLeft = fitNode->m_pLeft; 87 } 88 else 89 { 90 parents->m_pRight = temp; 91 temp ->m_pLeft = fitNode->m_pLeft; 92 } 93 } 94 else 95 { 96 pCurrent = temp; 97 } 98 } 99 } 100 }

      //以下是對二叉查找樹的操作實例

    1 int main() 2 { 3 BiTNode * root = NULL,*p; 4 addBSTreeNode(root,15); 5 addBSTreeNode(root,6); 6 addBSTreeNode(root,18); 7 addBSTreeNode(root,3); 8 addBSTreeNode(root,7); 9 addBSTreeNode(root,17); 10 addBSTreeNode(root,20); 11 addBSTreeNode(root,2); 12 addBSTreeNode(root,4); 13 addBSTreeNode(root,13); 14 addBSTreeNode(root,9); 15 p = searchBSTreeNode(root,18); 16 if(p) cout << &p << ":" << p->m_Value << endl; 17 else cout << "不存在!" << endl; 18 cout << "最大值:" <<getMaxValueFromBSTree(root)->m_Value << endl; 19 cout << "最小值:" <<getMinValueFromBSTree(root)->m_Value << endl; 20 cout << "2后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,2))->m_Value << endl; 21 cout << "3后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,3))->m_Value << endl; 22 cout << "4后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,4))->m_Value << endl; 23 cout << "6后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,6))->m_Value << endl; 24 cout << "7后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,7))->m_Value << endl; 25 cout << "9后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,9))->m_Value << endl; 26 cout << "13后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,13))->m_Value << endl; 27 cout << "15后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,15))->m_Value << endl; 28 cout << "17后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,17))->m_Value << endl; 29 cout << "18后繼結點值為:" << getSuccessorNode(root,searchBSTreeNode(root,18))->m_Value << endl; 30 31 32 cout << "3前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,3))->m_Value << endl; 33 cout << "4前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,4))->m_Value << endl; 34 cout << "6前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,6))->m_Value << endl; 35 cout << "7前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,7))->m_Value << endl; 36 cout << "9前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,9))->m_Value << endl; 37 cout << "13前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,13))->m_Value << endl; 38 cout << "15前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,15))->m_Value << endl; 39 cout << "17前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,17))->m_Value << endl; 40 cout << "18前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,18))->m_Value << endl; 41 cout << "20前驅結點值為:" << getPredecessorNode(root,searchBSTreeNode(root,20))->m_Value << endl; 42 43 deleteNodeFromBSTreeNode(root,15); 44 inOrderVisitUseRecur(root); 45 cout << endl; 46 return 0; 47 }

      //以上代碼全部本人手工敲上去的,如有錯誤請留言。如若轉載,請注明出處!

    ?

    ?

    轉載于:https://www.cnblogs.com/zhuwbox/p/3634883.html

    總結

    以上是生活随笔為你收集整理的数据结构树之二分查找树的全部內容,希望文章能夠幫你解決所遇到的問題。

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