zoukankan      html  css  js  c++  java
  • 查找之二叉树查找

    1.      查找树的创建(createTree)

    假设有如下数组4,1,45,78,345,23,12,3,6,21

    首先选定4为root,然后遍历剩下的数字,如果大于等于4则放到4的右侧,小于4放到4的左侧,最后构建成的树:所有的左孩子都小于父节点,所有的右孩子都大于等于父节点。如下图:

    2.      遍历查找树(displayTree)

    按照左中右的顺序遍历树,结果为:1,3,4,5,12,21,23,45,78,345,遍历的结果就是已经排好序的数字。

    3.      查找树中的节点(searchTree)

    从根节点开始,如果大于等于根节点,则查找根节点的右侧;如果小于根节点,则查找根节点的左侧,直到查找到节点。

    比如要查找12:

    比4大,往右走;

            比45小,往左走;

            比23小,往左走;

            找到12

    4.      删除树中的节点(deleteNode)

    这个是最复杂的,因为删除完节点后要重新构建树,涉及到的情况很多:

    a.要删除的node没有左右孩子,有父节点。

    如果要删除的node为父节点的左孩子,则将父节点的左孩子指针设置为NULL;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为NULL。最后删除node。

    b.要删除的node没有左右孩子,没有父节点(即根节点)。

    根节点设为NULL,删除node。

    c.要删除的node有左孩子没右孩子,有父节点

    如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。

    d.要被删除的node有左孩子没有右孩子,没有父节点

            将要被删除的node的左孩子设置为根节点,删除node。

    e.要删除的node有右孩子没左孩子,有父节点

    如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的右孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的右孩子。最后删除node。

     f.要被删除的node有右孩子没有左孩子,没有父节点

            将要被删除的node的右孩子设置为根节点,删除node。

     g.要被删除的node左右孩子都有,有父节点

    将要被删除node的右孩子插入到左孩子中去。如果要删除的node为父节点的左孩子,则将父节点的左孩子设置为要被删除node的左孩子;如果要删除的node为父节点的右孩子,则将父节点的右孩子指针设置为要被删除node的左孩子。最后删除node。

    h.要被删除的node左右孩子都有,无父节点

    将要被删除node的右孩子插入到左孩子中去,父节点修改为要被删除node的左孩子,删除node节点。

    c代码如下:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define SIZE 10
      5 
      6 typedef struct tagNode{
      7         int value;
      8         struct tagNode* left;
      9         struct tagNode* right;
     10 }treeNode;
     11 
     12 //打印数组
     13 void displayArray(int array[],int size){
     14         printf("the array is:");
     15         int i;
     16         for(i=0;i<size;i++){
     17                 printf("%d ",array[i]);
     18         }
     19         printf("
    ");
     20 }
     21 
     22 //按左中右顺序遍历树
     23 void displayTree(treeNode* node){
     24         if(node == NULL) return;
     25 
     26         if(node->left != NULL){
     27                 displayTree(node->left);
     28         }
     29 
     30         printf("%d ",node->value);
     31 
     32         if(node->right != NULL){
     33                 displayTree(node->right);
     34         }
     35 }
     36 
     37 //查找以node为节点的树中上是否存在vlaue的节点
     38 treeNode* searchTree(treeNode* node, int value){
     39         if(node->value == value){
     40                 return node;
     41         }else if(node->value > value){
     42                 if(node->left != NULL){
     43                         return searchTree(node->left, value);
     44                 }else{
     45                         return NULL;
     46                 }
     47         }else{
     48                 if(node->right != NULL){
     49                         return searchTree(node->right, value);
     50                 }else{
     51                         return NULL;
     52                 }
     53         }
     54 }
     55 
     56 //查找以node为节点的树中上是否存在vlaue的节点,parent为查找到的节点的父节点。
     57 //dir为1表示parent节点的左节点为查找结果
     58 //dir为2表示parent节点的右节点为查找结果
     59 treeNode* searchTreeWithParent(treeNode* node, treeNode** parent, int* dir, int value){
     60         if(node->value == value){
     61                 return node;
     62         }else if(node->value > value){
     63                 if(node->left != NULL){
     64                         *dir = 1;
     65                         *parent = node;
     66                         return searchTreeWithParent(node->left, parent, dir, value);
     67                 }else{
     68                         return NULL;
     69                 }
     70         }else{
     71                 if(node->right != NULL){
     72                         *dir = 2;
     73                         *parent = node;
     74                         return searchTreeWithParent(node->right, parent, dir, value);
     75                 }else{
     76                         return NULL;
     77                 }
     78         }
     79 }
     80 
     81 //将iNode插入到以node为根节点的树中
     82 void insertNode(treeNode* node, treeNode* iNode){
     83         if(iNode->value >= node->value && node->right != NULL){
     84                 insertNode(node->right, iNode);
     85                 return;
     86         }
     87 
     88         if(iNode->value < node->value && node->left != NULL){
     89                 insertNode(node->left, iNode);
     90                 return;
     91         }
     92 
     93         if(iNode->value >= node->value && node->right == NULL){
     94                 node->right = iNode;
     95         }
     96 
     97         if(iNode->value < node->value && node->left == NULL){
     98                 node->left = iNode;
     99         }
    100 }
    101 
    102 //从以root为根节点的树中删除值为value的节点
    103 void deleteNode(treeNode** root, int value){
    104         treeNode* parent = NULL;
    105         int dir = -1;
    106         treeNode* deleteNode = searchTreeWithParent(*root,&parent,&dir,value);
    107         if(deleteNode == NULL){
    108                 printf("%s
    ", "node not found");
    109         }else{
    110                 if(deleteNode->left == NULL && deleteNode->right == NULL){
    111             //对应说明中的a
    112                         if(parent != NULL){
    113                                 if(dir == 1)
    114                                         parent->left = NULL;
    115                                 else
    116                                         parent->right = NULL;
    117                         }else{//对应说明中的b
    118                                 *root = NULL;
    119                         }
    120                 }else if(deleteNode->left != NULL && deleteNode->right == NULL){
    121                         //对应说明中的c
    122             if(parent != NULL){
    123                                 if(dir == 1)
    124                                         parent->left = deleteNode->left;
    125                                 else
    126                                         parent->right = deleteNode->left;
    127                         }else{//对应说明中的d
    128                                 *root = deleteNode->left;
    129                         }
    130                 }else if(deleteNode->left == NULL && deleteNode->right != NULL){
    131                         //对应说明中的e
    132             if(parent != NULL){
    133                                 if(dir == 1)
    134                                         parent->left = deleteNode->right;
    135                                 else
    136                                         parent->right = deleteNode->right;
    137                         }else{//对应说明中的f
    138                                 *root = deleteNode->right;
    139                         }
    140                 }else{
    141                         insertNode(deleteNode->left,deleteNode->right);
    142                         //对应说明中的g
    143             if(parent != NULL){
    144                                 if(dir == 1)
    145                                         parent->left = deleteNode->left;
    146                                 else
    147                                         parent->right = deleteNode->left;
    148                         }else{//对应说明中的h
    149                                 *root = deleteNode->left;
    150                         }
    151                 }
    152                 free(deleteNode);
    153                 deleteNode = NULL;
    154         }
    155 }
    156 
    157 //使用array数组中的数,创建以root为根节点的树,
    158 void createTree(treeNode** root, int array[], int size){
    159         int i;
    160 
    161         *root = (treeNode*)malloc(sizeof(treeNode));
    162         (*root)->value = array[0];
    163         (*root)->left = NULL;
    164         (*root)->right = NULL;
    165 
    166         for(i=1;i<size;i++){
    167                 treeNode* child = (treeNode*)malloc(sizeof(treeNode));
    168                 child->value = array[i];
    169                 child->left = NULL;
    170                 child->right = NULL;
    171                 insertNode(*root, child);
    172         }
    173 }
    174 
    175 //删除以node为根节点的树
    176 void deleteTree(treeNode* node){
    177         if(node == NULL) return;
    178 
    179         if(node->left != NULL){
    180                 deleteTree(node->left);
    181         }
    182 
    183         if(node->right != NULL){
    184                 deleteTree(node->right);
    185         }
    186 
    187         if(node->left == NULL && node->right == NULL){
    188                 free(node);
    189                 node = NULL;
    190         }
    191 }
    192 
    193 int main(int argc, char* argv[]){
    194 
    195         int array[SIZE] = {4,1,45,78,345,23,12,3,6,21};
    196         displayArray(array,SIZE);
    197 
    198         treeNode *root = NULL;
    199 
    200         createTree(&root, array, SIZE);
    201 
    202         printf("the tree is(left->middle->right):");
    203         displayTree(root);
    204         printf("
    ");
    205 
    206         int value = atoi(argv[1]);
    207         treeNode* parent = NULL;
    208         int dir = -1;
    209         printf("search value %d:",value);
    210         if(searchTree(root,value) != NULL){
    211                 printf("%s
    ","exist");
    212         }else{
    213                 printf("%s
    ","not exist");
    214         }
    215 
    216         printf("delete value:%d ",value);
    217         deleteNode(&root,value);
    218         printf("
    ");
    219         printf("the tree is(left->middle->right):");
    220         displayTree(root);
    221         printf("
    ");
    222 
    223         deleteTree(root);
    224         return 0;
    225 }
  • 相关阅读:
    用户控件JS问题
    jQuery formValidator自定义函数扩展功能
    IAR使用notice
    C++入门学习
    解决Myeclipse闪退问题
    Cortex_M3——存储器系统学习笔记
    加密算法中涉及C/C++总结
    学习笔记——应用密码学基础
    keil软件相关问题汇总
    STM32知识点纪要
  • 原文地址:https://www.cnblogs.com/zl1991/p/4759099.html
Copyright © 2011-2022 走看看