一步一步寫數據結構(BST-二叉排序樹)


二叉排序樹的重要性不用多說,下面用c++實現二叉排序樹的建立,插入,查找,修改,和刪除。難點在於刪除,其他幾個相對比較簡單。

以下是代碼:

  1 #include<iostream>
  2 using namespace std;
  3 //定義節點
  4 typedef struct BiNode
  5 {
  6     int data;
  7     struct BiNode *lchild,*rchild;
  8 }BiNode,*BiTree;
  9 
 10 //插入函數
 11 void insertBST(BiTree &T,int key)
 12 {
 13     if(NULL==T)
 14     {
 15         T=new BiNode;
 16         T->data=key;
 17         T->lchild=T->rchild=NULL;
 18     }
 19     else if(T->data==key)
 20         cout<<"不能重復!";
 21     else if(T->data>key)
 22         insertBST(T->lchild,key);
 23     else
 24         insertBST(T->rchild,key);
 25 
 26 }
 27 //通過插入函數實現創建二叉排序樹
 28 void createBST(BiTree &T)
 29 {
 30     int n;
 31     cout<<"請輸入要插入的節點數: ";
 32     cin>>n;
 33     int a[n];
 34     cout<<"請輸入要插入的數據:中間用空格分開"<<endl;
 35     for(int i=0;i<n;i++)
 36     {
 37         cin>>a[i];
 38         insertBST(T,a[i]);
 39     }
 40 
 41     cout<<"創建二叉排序樹完成!"<<endl;
 42 
 43 }
 44 
 45 //前序遍歷並打印
 46 void preOrderTraverse(BiTree T)
 47 {
 48     if(T)
 49     {
 50         cout <<T->data<< " ";
 51         preOrderTraverse(T->lchild);
 52         preOrderTraverse(T->rchild);
 53     }
 54 }
 55 //中序遍歷並打印
 56 void midOrderTraverse(BiTree T)
 57 {
 58 
 59     if(T)
 60     {
 61         midOrderTraverse(T->lchild);
 62         cout <<T->data<< " ";
 63         midOrderTraverse(T->rchild);
 64     }
 65 }
 66 
 67 //定義全局變量layer,表示層數
 68 int layer=0;
 69 //下面是查找函數,返回是否查找到數據並且可以確定查找元素的層數
 70 bool searchBST(BiTree &T,int key)
 71 {
 72     layer++;
 73     if(T==NULL)
 74     {
 75         return false;
 76     }
 77     else
 78     {
 79         if (key==T->data)
 80         {
 81 
 82             return true;
 83 
 84         }
 85         else if(key<T->data)
 86             searchBST(T->lchild,key);
 87         else
 88             searchBST(T->rchild,key);
 89     }
 90 }
 91 //利用上面查找函數實現查找操作
 92 void findBST(BiTree &T)
 93 {
 94     int k;
 95     cout<<"請輸入要查找的元素值: ";
 96     cin>>k;
 97     if(searchBST(T,k))
 98     {
 99         cout<<"查找成功,該元素位於二叉樹中!"<<endl;
100         cout<<"層數為:"<<layer<<endl;
101     }
102 
103     else
104         cout<<"沒有查找到該元素!"<<endl;
105 }
     //定義刪除節點的函數
106 void deletenode(BiTree &p) 107 { 108 BiTree q,s; //函數形參P指向要刪除的節點,即它的雙親節點的rchild 109 //根據要刪除的節點的孩子情況分三種討論 110 //沒有左孩子 111 if(!p->lchild) 112 { 113 q=p; 114 p=p->rchild; 115 delete q; 116 } 117 //沒有右孩子 118 if(!p->rchild) 119 { 120 q=p; 121 p=p->lchild; 122 delete q; 123 124 } 125 //兩個孩子都有 126 else 127 { 128 q=p; //q指向上一個節點,s指向下一個節點,即指向q的右孩子,初始時q=p,最終s指向跟p節點換值的那個節點。 129 s=q->lchild; 130 131 while(s->rchild)    //通過這個循環實現尋找最接近要刪除節點(p)值的節點 132 { 133 q=s; 134 s=s->rchild; 135 } 136 p->data=s->data;    //交換值,有個注意事項,s是不存在右孩子的,因為如果存在,則右孩子比他大,更接近p,s需要繼續循環,最終s還是沒有右孩子。 137 if(q!=p)           138 { 139 q->rchild=s->lchild; 140 } 141 else        //如果q,s 沒有移動,即此時q=p,s的初始值就是最接近p點的節點,此時q不存在右節點,需要單獨討論
142 { 143 q->lchild=s->lchild;       144 } 145 delete s; 146 } 147 148 149 } 150 151 //刪除操作 152 bool deleteBST(BiTree &T,int del) 153 { 154 if(!T) 155 return false; 156 else 157 { 158 if(T->data==del) 159 { 160 deletenode(T); 161 return true; 162 } 163 else if(del<T->data) 164 { 165 return deleteBST(T->lchild,del); 166 } 167 else 168 { 169 return deleteBST(T->rchild,del); 170 } 171 } 172 173 } 174

 下面是主函數:

 1 //主函數
 2 int main()
 3 {
 4     BiTree T=NULL;
 5     int d;
 6     createBST(T);
 7     cout<<"前序遍歷的結果為:"<<endl;
 8     preOrderTraverse(T);
 9     cout<<endl;
10     cout<<"中序遍歷的結果為:"<<endl;
11     midOrderTraverse(T);
12     cout<<endl;
13     findBST(T);
14     cout<<"請輸入要刪除的數據:"<<endl;
15     cin>>d;
16     deleteBST(T,d);
17     cout<<"前序遍歷的結果為:"<<endl;
18     preOrderTraverse(T);
19 
20 }

 

上面的代碼分別實現了查找,建立,插入和刪除的操作,刪除比較難主要是因為刪除節點后下面的所有節點都會受到影響。此時采取的思維是分類討論節點的孩子節點情況,

最復雜的情況是存在左右孩子,此時有兩種思路,對左邊孩子樹進行操作或者對右邊孩子樹進行操作,我給出的代碼是左邊,二者道理一樣。具體方法參考代碼,說明很詳細。

下面給出一個存在雙孩子節點的圖

 

畫的雖然簡陋,但大概意思就這樣,(畫圖的確是理解數據結構的利器啊)最后給出控制台運行結果:

 over~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM