c和指针 十七章课后练习 :链式二叉树 及其拓展功能


#include <stdio.h>
#include<assert.h>
#include<stdlib.h>
#define TREE_TYPE int
typedef struct tree{
    struct tree *left;
    struct tree *right;
    TREE_TYPE value;
} Treelist;
void insert(TREE_TYPE value);//1
Treelist** find(TREE_TYPE value);//1
void order_traverse(void (*) (TREE_TYPE value));//层次遍历 1
void show_value(TREE_TYPE value);//回调 遍历值打印 1
int node_num(Treelist *);//1
int is_tree(Treelist *);//1
void dele(TREE_TYPE value);//1
void destroy_tree(Treelist* current);//1

Treelist *root;

void
insert(TREE_TYPE value){
    Treelist **link;
    link =&root;
    
    while(*link != NULL){
        assert(value != (*link)->value);
        if(value > (*link)->value ){
            link = &(*link)->right;
        }
            else{
                link = &(*link)->left;//
            }
    }
    //
    *link = malloc(sizeof(Treelist));
     assert( *link !=NULL );
    (*link)->left=NULL;
    (*link)->right=NULL;
    (*link)->value = value;
    
    puts("插入成功");
}

Treelist**
find(TREE_TYPE value){
    assert(root); //检查是否存在
    Treelist **link;
    link =&root;
    while(*link !=NULL){
        if(value == (*link)->value){
            show_value((*link)->value);
            printf(" 找到了\n");
            return link;
        }
        else {
            if(value >(*link)->value)
                link = &(*link)->right;
                else
                link = &(*link)->left;
          
        }
    }
    puts("没找到");
    return NULL;
}
void
show_value(TREE_TYPE value){
    printf("%d ",value);
}
int
node_num(Treelist *current){
    static int num =0;
    if(current != NULL){
        num++;
        node_num(current->left); //递归
        node_num(current->right);
    }
    return num;
}
int
is_tree(Treelist *node){
    assert(node !=NULL);
      int  root_num= node->value;
       if(node ->left != NULL){
          if(node->left->value >=root_num )
              return 0;
            is_tree(node->left);
             
        }
        if(node->right !=NULL){
            if(node->right->value <= root_num)
             return 0;
            is_tree(node->right);
        }
    
    return 1;
}
void
order_traverse(void (*call) (TREE_TYPE value)){
    call = show_value;
    Treelist *tree_queue[50]={0};  // size == 50
    int front=1;
    int rear=0;
      tree_queue[++rear]= root;//向一个队列添加根节点 0空出循环数组
    while ( tree_queue[front] !=NULL ){ //非空
        call( tree_queue[front]->value );//出队列
        
        //孩子添加到队
        if(tree_queue[front]->left !=NULL){
            rear= (rear+1)%50;
            tree_queue[rear]=tree_queue[front]->left;
        }
        if(tree_queue[front]->right != NULL){
        rear= (rear+1)%50;
        tree_queue[rear]=tree_queue[front]->right;
        }
        front= (front +1) %50;
    }
    printf("\n层次遍历成功!\n");
    
}
void
destroy_tree(Treelist* current){
    if(current != NULL){
        node_num(current->left); //递归
        node_num(current->right);
        free(current);
    }
     puts("全部释放完成!\n");
    
}
void
dele(TREE_TYPE value){
    Treelist **de_link= find(value) ;
    Treelist *temp=NULL;
        if(de_link== NULL){
           printf("没找到,删除失败!\n");
            exit(1);
        }
        else{
            if( (*de_link)->left == NULL && (*de_link)->right ==NULL){//没孩子
                *de_link  =temp;
                (*de_link) =NULL;
                free(temp);
            }
            else if((*de_link)->left == NULL ^ (*de_link)->right ==NULL){//有一个
                    if( (*de_link)->left == NULL){
                        *de_link  =temp;
                        *de_link =temp->right;
                        free(temp);
                    }
                    else {
                        *de_link  =temp;
                        *de_link =temp->left;
                        free(temp);
                    }
                         
                }
            else{//删除左子树最大那一个 替换双亲   有两个孩子!
                int left_max= (*de_link)->left->value;
                temp= (*de_link)->left;
                (*de_link)->left =NULL;
                free(temp);
                (*de_link)->value = left_max;
            }
            
        }
    puts("删除完成!\n");
}

int main(){
    void (*call)(TREE_TYPE ) = show_value;

    insert(6);
    insert(8);
    insert(100);
    insert(9);
    find(100);
    
   order_traverse(call);
    printf("一共有%d 个叶子\n",node_num(root));
    if(is_tree(root) ){
        printf("是二叉树\n");
    };
    dele(666);
    order_traverse(call);
    destroy_tree(root);
    return 0;
}

犯了一个错误

错把

 *link = (*link)->next;
 link = &(*link)->next;

这两行代码等价 其实不然 

第一个修改了 *link 也就是 root ;

代码还有许多缩减的地方

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值