二叉排序树的详细实现(转)

//原址:http://blog.csdn.net/touch_2011/article/details/6831924

1、序

     详细实现了二叉查找树的各种操作:插入结点、构造二叉树、删除结点、查找、  查找最大值、查找最小值、查找指定结点的前驱和后继

2、二叉查找树简介

     它或者是一棵空树;或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值; (3)左、右子树也分别为二叉排序树

3、二叉查找树的各种操作

        此处给出代码,注释非常详细,具体操作请参考代码:

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值