该博客通过代码来展示对二叉排序树的各种操作:
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 typedef int KeyType; 5 6 typedef struct Node 7 { 8 KeyType key;//关键字 9 struct Node *left;//左孩子指针 10 struct Node *right;//右孩子指针 11 struct Node *parent;//指向父亲节点的指针 12 }Node,*PNode; 13 14 /* 15 *往二叉排序树中插入节点 16 *插入的话,可能要改变根节点的地址,所以传的是二级指针 17 */ 18 19 void insert(PNode *root,KeyType key) 20 { 21 //初始化插入节点 22 PNode p=(PNode)malloc(sizeof(Node)); 23 p->key=key; 24 p->left=p->right=p->parent=NULL; 25 //空树时,直接作为根节点 26 if((*root)==NULL) 27 { 28 *root=p; 29 return ; 30 } 31 //插入到当前节点的左孩子 32 if((*root)->left==NULL&&(*root)->key>key) 33 { 34 p->parent=(*root); 35 (*root)->left=p; 36 return ; 37 } 38 //插入到当前节点的右孩子 39 if((*root)->right==NULL&&(*root)->key<key) 40 { 41 p->parent=(*root); 42 (*root)->right=p; 43 return ; 44 } 45 if((*root)->key>key) 46 { 47 insert(&(*root)->left,key); 48 } 49 else if((*root)->key<key) 50 insert(&(*root)->right,key); 51 else return; 52 } 53 54 //查找元素,找到返回关键字的结点指针,没有找到返回NULL 55 56 PNode search(PNode root,KeyType key) 57 { 58 if(root==NULL) 59 return NULL; 60 if(key>root->key)//查找右子树 61 return search(root->right,key); 62 else if(key<root->key)//查找左子树 63 return search(root->left,key); 64 else 65 return root; 66 //查找最小关键字。空树时返回NULL 67 PNode searchMin(PNode root) 68 { 69 if(root==NULL) 70 return NULL; 71 if(root->left==NULL) 72 return root; 73 else //一直往左孩子找 74 return searchMin(root->left); 75 } 76 77 //查找最大关键字,空树时返回NULL 78 PNode searchMax(PNode root) 79 { 80 if(root==NULL) 81 return NULL; 82 if(root->right==NULL) 83 return root; 84 else //一直往右孩子找 85 return searchMax(root->right); 86 } 87 /* 88 *根据关键字删除某个结点,删除成功返回1,否则返回0; 89 *如果把结点删掉,那么要改变根节点的地址,所以传二级指针 90 */ 91 int deleteNode(PNode *root,KeyType key) 92 { 93 PNode q; 94 //查找要删除的结点 95 PNode p=search(*root,key); 96 KeyType temp;//暂存后继结点的值 97 if(!p) 98 return 0; 99 //1.被删的结点是叶子结点,直接删除 100 if(p->left==NULL&&p->right==NULL) 101 { 102 //只有一个元素,删完后变成空树 103 if(p->parent==NULL) 104 { 105 free(p); 106 (*root)=NULL: 107 } 108 else{ 109 if(p->parent->left==p) 110 p->parent->left=NULL; 111 else 112 p->parent->right=NULL; 113 free(p); 114 } 115 } 116 //2.被删除的结点只有左子树 117 else if(p->left&&!(p->right)) 118 { 119 p->left->parent=p->parent; 120 if(p->parent==NULL) 121 *root=p->left; 122 else if(p->parent->left==p) 123 p->parent->left=p->left; 124 else 125 p->parent->right=p->left; 126 free(p); 127 } 128 //3.被删除的结点只有右孩子 129 else if(p->right&&!(p->left)) 130 { 131 p->right->parent=p->parent; 132 //如果删除是父结点,要改变父节点指针 133 if(p->parent == NULL) 134 *root=p->right; 135 //删除的结点是父节点的左孩子 136 else if(p->parent->left == p) 137 p->parent->left=p->right; 138 else //删除的结点是父节点的右孩子 139 p->parent->right=p->right; 140 free(p); 141 } 142 //4.被删除的结点既有左孩子,又有右孩子 143 //该结点的后继结点肯定无左子树(参考上面查找后继结点函数) 144 //删掉后继结点,后继结点的值代替该结点 145 else{ 146 //找到要删除结点的后继 147 q=searchSuccessor(p); 148 temp=q->key; 149 //删除后继结点 150 deleteNode(root,q->key); 151 p->key=temp; 152 } 153 return 1; 154 } 155 156 //创建一棵二叉排序树 157 void create(PNode *root,KeyType *keyArray,int length) 158 { 159 int i; 160 for(i=0;i<length;i++) 161 insert(root,keyArray[i]); 162 } 163 164 int main(void) 165 { 166 int i; 167 PNode root=NULL; 168 KeyType nodeArray[11]={15,6,18,3,7,17,20,2,4,13,9}; 169 create(&root,nodeArray,11); 170 for(i=0;i<2;i++) 171 deleteNode(&root,nodeArray[i]); 172 printf("%d ",searchMin(root)->key); 173 printf("%d ",searchMax(root)->key); 174 printf("%d ",search(root,13)->key); 175 return 0; 176 } 177 }