关于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);
}
希望能够帮助到需要的小伙伴理解二叉树和二叉搜索树的编写。