关于C/C++二叉树的数据结构

关于C/C++二叉树的数据结构

首先简单的说明一下什么是二叉树,就是每个节点都最多只包含两个子节点,因此个人感觉是树里边查找和建树相对比较方便的。

二叉树的排序有三种:

​ 1.前序遍历(根-左-右)

​ 2.中序遍历(左-根-右)

​ 3.后序遍历(左-右-根)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sOzxvILC-1587881125645)(D:\photo\树的排序.jpg)]在这里插入图片描述

这里给出树的递归遍历的过程:

#include<algorithm>
#include<string>
#include<cstring>
#include<set>
#include<map>
#include<cstdlib>
#include<cstdio>
#include<vector>
#include<iostream>
using namespace std;


typedef struct node{
    char data;
    struct node* left;
    struct node* right;
}Node;

//递归的先序遍历(根-左-右)
void preorder(Node* p){
    if(p != NULL){
        printf("%c\n", p->data);
        preorder(p->left);
        preorder(p->right);
    }
}

//递归方式的中序遍历(左-根-右)
void inorder(Node* p){
    if(p != NULL){
        inorder(p->left);
        printf("%c\n",p->data);
        inorder(p->right);
    }
}


//递归方式的后序遍历(左-右-根)
void postorder(Node* p){
    if(p != NULL){
        postorder(p->left);
        postorder(p->right);
        printf("%c\n",p->data);
    }
}

int main(){
    Node n1;
    Node n2;
    Node n3;
    Node n4;

    n1.data = 'A';
    n2.data = 'B';
    n3.data = 'C';
    n4.data = 'D';

    n1.left = &n2;
    n1.right = &n3;
    n2.left = &n4;
    n2.right = NULL;
    n3.left = NULL;
    n3.right = NULL;
    n4.left = NULL;
    n4.right = NULL; 

    preorder(&n1);
}

二叉搜索树:满足左子树的值小于根节点的值,右节点的值大于根节点的值,这样的二叉树就叫做二叉搜索树

建树过程:传入一个树的结构体指针,和传入的值,拿该值和根节点的值作比较,比根节点的值小就插入该节点的左边,若比根节点的值大就插入该节点的右边,然后这样继续下去,直到插入完成所有的值,就完成了二叉搜索树的建立。这里强调一点二叉搜索树的中序遍历就是值的从小到大的排序。

这里给出建树,递归遍历、非递归遍历、求树的高度和求树中的最大值的代码(从B站大佬学到的:给了我觉得重要的注释,可以帮助理解代码)

#include <cstdio>
#include <cstdlib>
#include <stdlib.h>
#include <malloc.h>
#include <cstring>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

//节点的结构
typedef struct node{
    int data;
    struct node* left;
    struct node* right;

}Node;
//树的结构
typedef struct {
    Node* root;
}Tree;

//建树的过程
void insert(Tree* tree,int value){
    //动态分配内存
    Node* node = (Node* )malloc(sizeof(Node));
    node->data = value;
    node->left = NULL;
    node->right = NULL;

    if(tree->root == NULL){
        tree->root = node;
    }else{
        //定义一个节点设置为根节点
        Node* temp = tree->root;
        //判断temp节点是否为空
        while(temp != NULL){
            //判断该值是否小于temp左节点的值
            if(value < temp->data){
                //判断左节点的值是否为空,如果为空,直接将当前节点插入,否则继续查找该节点的左节点下去
                if(temp->left == NULL){
                    temp->left = node;
                    return ;
                }else{
                    temp = temp->left;
                }
            }
            else{
                if(temp->right == NULL){
                    temp->right = node;
                    return ;
                }else{
                    temp = temp->right;
                }
            }
        }
    }
}

//求树的高度
int getheight(Node* node){
    if(node == NULL){
        return 0;
    }else{
        int letf_h = getheight(node->left);
        int right_h = getheight(node->right);
        int temp = letf_h;
        if(temp < right_h){
            temp = right_h;
        }
        return temp+1;
    }
}

//在一般的二叉树中求树中的最大值
int get_maximum(Node* node){
    if(node == NULL){
        return -1;
    }
    else{
        int m1 = get_maximum(node->left);
        int m2 = get_maximum(node->right);
        int m3 = node->data;
        int maxn = m1;
        if(maxn < m2){
            maxn = m2;
        }
        if(maxn < m3){
            maxn = m3;
        }
        return maxn; 
    }
}

//递归的先序遍历(根-左-右)
void preorder(Node* p){
    if(p != NULL){
        printf("%d\n", p->data);
        preorder(p->left);
        preorder(p->right);
    }
}

//非递归的先序遍历(根-左-右)
void preorderf(Node* p){     //传入的参数为树的单个节点
    stack<Node*> sk;
    while(p || !sk.empty()){
        if(p){
            printf("%c\n",p->data);
            sk.push(p);
            p = p->left;
        }
        else{
            Node* q = sk.top();
            sk.pop();
            p = q->right;
        }
    }
}

//递归方式的中序遍历(左-根-右)
void inorder(Node* p){
    if(p != NULL){
        inorder(p->left);
        printf("%d\n",p->data);
        inorder(p->right);
    }
}

//非递归的中序遍历(左-根-右)
void inorderf1(Tree *tree){    //传入的参数为数
    stack<Node*> s;
    Node* p = tree->root;
    while(p || !s.empty()){    //当p指针有值,且栈不为空的时候
        if(p){                  //当p有值,先存入栈中,在左子树下继续找,直到为空为止
            s.push(p);
            p = p->left;
        }
        else{
            Node *q = s.top();
            printf("%c\n",q->data);
            p = q->right;
        }
    }
}
//非递归的中序遍历
void inorderf2(Node* p){    //传入的参数为单个节点
    stack<Node*> sk;
    while(p || !sk.empty()){
        if(p){
            sk.push(p);
            p = p->left;
        }
        else{
            Node *q = sk.top();
            printf("%c\n", q->data);
            p = q->right;
        }
    }
}

//递归方式的后序遍历(左-右-根)
void postorder(Node* p){
    if(p != NULL){
        postorder(p->left);
        postorder(p->right);
        printf("%d\n",p->data);
    }
}

//非递归的后序遍历(左-右-根)方法:先类似于先序存入,再反转输出(先根-右-左存入,再反转取出)
void postorderf(Node* p){
    vector<char> res;
    stack<Node*> sk;
    while(p || !sk.empty()){
        if(p){
            sk.push(p);
            res.push_back(p->data);
            p = p->right;
        }
        else{
            Node *q = sk.top();
            sk.pop();
            p = q->left;
        }
    }
    reverse(res.begin(),res.end());
    for(auto it = res.begin(); it != res.end(); it++){
        printf("%c\n",*it);
    }
}


int main(){
    int arr[] = {6, 3, 8, 2, 5, 1, 7};
    Tree tree;
    tree.root = NULL;
    for(int i = 0; i < 7; i++){
        insert(&tree, arr[i]);
    }
    inorder(tree.root);
}

希望能够帮助到需要的小伙伴理解二叉树和二叉搜索树的编写。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值