1. 程式人生 > >數據結構【查找】—二叉樹排序以及查找

數據結構【查找】—二叉樹排序以及查找

數據 存在 binary 結點 ear style define 中間 color

講解:

  總結一句話:

    小的左邊,大的放右邊。

  特點:    

    二叉排序樹(Binary Sort Tree),又稱為二叉查找樹。它或者是一棵空樹,或者是具有下列性質的二叉樹。

    若它的左子樹不空,則左子樹上所有結點的值均小於它的根結構的值;

    若它的右子樹不空,則右子樹上所有結點的值均大於它的根結點的值;  

    它的左、右子樹也分別為二又排序樹。

技術分享圖片

二叉樹創建代碼:

 1 //創建二叉樹
 2 void InsertBST(BiTree* &T, int elem) {
 3     BiTree *p = new  BiTree;
4 p->data = elem; 5 p->lchild = NULL; 6 p->rchild = NULL; 7 if (!T) { 8 T = p;//為空樹 9 return; 10 } 11 12 if (T->data == elem) 13 return;//此數已經存在 14 15 while (true) { 16 if (elem > T->data) { 17 if
(T->rchild != NULL) 18 T = T->rchild;//走到最右端 19 else { 20 T->rchild = p;//添加為右子樹 21 return; 22 } 23 } 24 else { 25 if (T->lchild != NULL) 26 T = T->lchild;//走到最左端 27
else { 28 T->lchild = p;//添加為左子樹 29 return; 30 } 31 } 32 } 33 34 }

  二叉樹排序:

    通過二叉樹的中序遍歷,得到的就是一個有序數組

  代碼:  

1 void ShowTree(BiTree *T) {
2     //進行中序瀏覽
3     if (T) {
4         ShowTree(T->lchild);
5         cout << T->data << "—>";
6         ShowTree(T->rchild);
7     }
8 }

二叉樹查找:

  使用遞歸,通過比較大小來找到左子樹或右子樹。

  技術分享圖片

  二叉樹查找代碼:  

1 //對二叉樹進行查找工作
2 int SearchData(BiTree *T, int num) {
3     if (!T)return 0;
4     if (T->data == num)return 1;
5     if (num > T->data)SearchData(T->rchild,num);
6     else SearchData(T->lchild, num);
7 }

二叉樹的刪除是重點也是難點:

  當要刪除節點位於右端末,即無右子樹,則用它的左子樹接替他的位置;

    技術分享圖片

  當要刪除節點位於左端末,即無左子樹,則用它的右子樹接替他的位置;

    技術分享圖片

  當要刪除節點位於中間,即既有左子樹,又有右子樹,用左子樹的最大數代替,即左子樹的最右端末。

    技術分享圖片

 刪除代碼:

 1 //進行刪除
 2 //重點,也是難點
 3 int Delete(BiTree* &T) {
 4     BiTree *p, *q;
 5     if (T->rchild == NULL) {//若該結點沒有右子樹,則將該節點的左子樹代替其,並刪除
 6         p = T;
 7         T = T->lchild;
 8         delete(p);
 9     }
10     else if (T->lchild == NULL) {//若該結點沒有左子樹,則將該節點的右子樹代替其,並刪除
11         p = T;
12         T = T->rchild;
13         delete(p);
14     }
15     else {//左右子樹都存在
16         p = T;
17         q = T->lchild;
18         while (q->rchild) {//走到T左支的末端,此時他是左邊最大的數
19             p = q;//記住前端點
20             q = q->rchild;
21         }
22         T->data = q->data;//前驅的數字用最右端數字代替
23         if (p != T)//將末端的左孩子連接,因為此時他是左端最大的數字
24             p->rchild = q->lchild;
25         else
26             p->lchild = q->lchild;//重接左子樹
27         delete(q);//釋放左端最大值
28     }
29     return 1;
30 }
31 
32 
33 //對二叉樹進行刪除操作
34 int DeleteBST(BiTree* &T, int num) {
35     if (!T)return false;
36     if (num == T->data) {
37         Delete(T);
38         return true;
39     }
40     else if (num > T->data)DeleteBST(T->rchild, num);
41     DeleteBST(T->lchild, num);
42 }

完整代碼:

  

  1 #include "000庫函數.h"
  2 
  3 #define MAXSIZE 100
  4 
  5 
  6 //二叉樹的結構
  7 struct BiTree
  8 {
  9     int data;
 10     BiTree *lchild, *rchild;
 11 };
 12 
 13 //創建二叉樹
 14 void InsertBST(BiTree* &T, int elem) {
 15     BiTree *p = new  BiTree;
 16     p->data = elem;
 17     p->lchild = NULL;
 18     p->rchild = NULL;
 19     if (!T) {
 20         T = p;//為空樹        
 21         return;
 22     }
 23 
 24     if (T->data == elem)
 25         return;//此數已經存在
 26 
 27     while (true) {
 28         if (elem > T->data) {
 29             if (T->rchild != NULL)
 30                 T = T->rchild;//走到最右端
 31             else {
 32                 T->rchild = p;//添加為右子樹
 33                 return;
 34             }
 35         }
 36         else {
 37             if (T->lchild != NULL)
 38                 T = T->lchild;//走到最左端
 39             else {
 40                 T->lchild = p;//添加為左子樹
 41                 return;
 42             }
 43         }
 44     }
 45 
 46 }
 47 
 48 void ShowTree(BiTree *T) {
 49     //進行中序瀏覽
 50     if (T) {
 51         ShowTree(T->lchild);
 52         cout << T->data << "—>";
 53         ShowTree(T->rchild);
 54     }
 55 }
 56 
 57 //對二叉樹進行查找工作
 58 int SearchData(BiTree *T, int num) {
 59     if (!T)return 0;
 60     if (T->data == num)return 1;
 61     if (num > T->data)SearchData(T->rchild,num);
 62     else SearchData(T->lchild, num);
 63 }
 64 
 65 
 66 //進行刪除
 67 //重點,也是難點
 68 int Delete(BiTree* &T) {
 69     BiTree *p, *q;
 70     if (T->rchild == NULL) {//若該結點沒有右子樹,則將該節點的左子樹代替其,並刪除
 71         p = T;
 72         T = T->lchild;
 73         delete(p);
 74     }
 75     else if (T->lchild == NULL) {//若該結點沒有左子樹,則將該節點的右子樹代替其,並刪除
 76         p = T;
 77         T = T->rchild;
 78         delete(p);
 79     }
 80     else {//左右子樹都存在
 81         p = T;
 82         q = T->lchild;
 83         while (q->rchild) {//走到T左支的末端,此時他是左邊最大的數
 84             p = q;//記住前端點
 85             q = q->rchild;
 86         }
 87         T->data = q->data;//前驅的數字用最右端數字代替
 88         if (p != T)//將末端的左孩子連接,因為此時他是左端最大的數字
 89             p->rchild = q->lchild;
 90         else
 91             p->lchild = q->lchild;//重接左子樹
 92         delete(q);//釋放左端最大值
 93     }
 94     return 1;
 95 }
 96 
 97 
 98 //對二叉樹進行刪除操作
 99 int DeleteBST(BiTree* &T, int num) {
100     if (!T)return false;
101     if (num == T->data) {
102         Delete(T);
103         return true;
104     }
105     else if (num > T->data)DeleteBST(T->rchild, num);
106     DeleteBST(T->lchild, num);
107 }
108 
109 int T032(void)
110 {
111     int i;
112     int a[10] = { 62,88,58,47,35,73,51,99,37,93 };
113     BiTree *T = new BiTree;
114     T = NULL;
115     BiTree *p;
116     for (i = 0; i < 10; i++) {
117         InsertBST(T, a[i]);
118         if (i == 0)
119             p = T;//記住頭結點的位置
120         T = p;//仍然返回頭結點,從頭結點開始重新遍歷
121     }
122     ShowTree(T);
123     cout << endl;
124     cout << "找到沒?" << endl << SearchData(T, 99) << endl;
125     p = T;//記住頭結點
126     DeleteBST(T, 93);
127     T = p;
128     ShowTree(T);
129     cout << endl;
130     p = T;//記住頭結點
131     DeleteBST(T, 37);
132     T = p;
133     ShowTree(T);
134     cout << endl;
135     return 0;
136 }

數據結構【查找】—二叉樹排序以及查找