数据结构--树

220 阅读3分钟

一、基本概念

1、二叉树、满二叉树、完全二叉树

二叉树:树中包含的各个节点的度不能超过 2,即只能是 0、1 或者 2;
满二叉树:除了叶子节点,每个节点的度都为2;
完全二叉树:除最后一层其余为满二叉树,最后一层节点依次从左到右分布。

二、代码

1、定义二叉树

typedef struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
} BiNode, *BiTree;

2、创建二叉树

int CreateTree(struct TreeNode** root) {
    int val;
    scanf_s("%d", &val);
    if (val <= 0) {
        *root = NULL;
        return 0;
  }

  *root = (struct TreeNode*)malloc(sizeof(struct TreeNode));
  if (!root) {
      printf("创建失败\n");
  }

  if (val > 0) {
      (*root)->val = val;
      CreateTree(&((*root)->left));
      CreateTree(&((*root)->right));
  }
  return 0;
}

struct TreeNode* Create(){
    int val;
    scanf("%d", &val);

    struct TreeNode* root = (struct TreeNode*)malloc(sizeof(struct TreeNode*));
    if (val <= 0) {
        return NULL;
    }

    if (!root) {
        printf("创建失败\n");
    }

    if (val > 0) {
        root->val = val;
        root->left = Create();
        root->right = Create();
    }

    return root;
}

3、二叉树的遍历

void PreOrderTree(struct TreeNode* root) {
    if (root == NULL) return;
    printf("%d ", root->val);
    PreOrderTree(root->left);
    PreOrderTree(root->right);
}

void InOrderTree(struct TreeNode* root) {
    if (root == NULL) return;
    InOrderTree(root->left);
    printf("%d ", root->val);
    InOrderTree(root->right);
}

void PostOrderTree(struct TreeNode* root) {
    if (root == NULL) return;
    PostOrderTree(root->left);
    PostOrderTree(root->right);
    printf("%d ", root->val);
}

4、二叉树算法设计

  • 普通二叉树算法框架
// 注意要根据返回值和传参对框架进行变形
void xx_fun(struct TreeNode* root)
{
    if(root == NULL){	
        //当该节点不存在时的行为
    }
    /* 
        对该节点的操作。
    */
    xx_fun(root->left);
    xx_fun(root->right);
}

//leetcode 100-相同的树
bool isSameTree(struct TreeNode* p, struct TreeNode* q){
    if(p == NULL && q == NULL) return true;	//两个节点都不存在时
    if(p == NULL || q == NULL) return false;	//一个节点不存在时
    if(p->val != q->val) return false;		//两个节点都存在时,但两点不同
						// 两个节点都存在,两点相同,则继续往下找。
    return (isSameTree(p->left,q->left))&&(isSameTree(p->right,q->right));
}

  • 二叉查找树算法框架(查、增、改、删、判)
模板1 -- 无返回值时
void xx_fun(struct TreeNode* root, int target) {
    if (root == NULL)
        // 节点不存在时
    if (root->val == target) //插入不需要这一步
        // 找到目标,做点什么
    else if (root->val < target) 
        xx_fun(root.right, target);
    else if (root->val > target)
        xx_fun(root.left, target);
}

模板2 -- 返回根节点时或者子节点时
struct TreeNode* xx_fun(struct TreeNode* root, int target) {
    if (root == NULL)
        // 节点不存在时
    if (root->val == target) //插入不需要这一步
        // 找到目标,做点什么
    else if (root->val < target) 
        root->right = xx_fun(root->right, target);	//返回值的关键点在这个式子的左边
    else if (root->val > target)
        root->left = xx_fun(root->left, target);
    
    rertun root;
}
//leetcode 450-删除二叉搜索树中的节点
struct TreeNode* getMaxNode(struct TreeNode* node)
{
    while(node->right!=NULL)
        node = node->right;
    return node;
}

struct TreeNode* deleteNode(struct TreeNode* root, int key){
    if(root == NULL) return NULL;
    if(root->val == key){
        if((root->left == NULL)&&(root->right == NULL))
            root = NULL;
        else if(root->left == NULL)
            root = root->right;
        else if(root->right == NULL)
            root = root->left;
        else{
            struct TreeNode* maxNode = getMaxNode(root->left);
            root->val = maxNode->val;
            root->left = deleteNode(root->left,maxNode->val);
        }
    } 
    else if(root->val > key)
        root->left = deleteNode(root->left,key);
    else if(root->val < key)
        root->right = deleteNode(root->right,key);
    return root;
}

//leetcode 701-二叉树中的插入操作
struct TreeNode* insertIntoBST(struct TreeNode* root, int val){
    if(root == NULL){
        struct TreeNode *tmp = malloc(sizeof(struct TreeNode));
        tmp->val = val;
        tmp->left = NULL;
        tmp->right = NULL;
        root = tmp;
    }
    else if (root->val > val)
        root->left = insertIntoBST(root->left,val);
    else if (root->val < val)
        root->right = insertIntoBST(root->right,val);
    return root;
}
模板3 返回值为boolbool xx_fun(struct TreeNode* root) {
    if(root == NULL) return ture;
	//对当前节点操作,罗列return false 的情况。
    if(!xx_fun(root->left))
    	return false;
  	if(!xx_fun(root->right))
    	return false;
    
    rertun ture;
}
//leetcode 700-二叉树中的搜索
long pre = LONG_MIN; 
bool isValidBST(struct TreeNode* root){
    if (root == NULL) return true;

    if(!isValidBST(root->left))
        return false;

    if(root->val <= pre)
        return false;
    pre = root->val;

    if (!isValidBST(root->right))
        return false;

    return true;   
}