二叉排序树

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值