一、二叉树
二叉树,顾名思义,就是每个节点都有两个分支,最后构成的树形结构。
1.先看一下二叉树每个节点的存储结构:
struct Node {
int val; //存储的值
Node* left;
Node* right; //分别代表左孩子和右孩子
};
Node* root = NULL; //根节点为空
2.再看一下如何创建一个新的节点:
Node* newNode(int x) {
Node* node = new Node();
node->val = x;
node->left = NULL;
node->right = NULL; //默认没有孩子
}
3.于是,我们就可以开始一些简单的基本操作:
3.1查找修改操作:
//查找修改操作
void find(Node* root, int x, int y) {
if (root == NULL) return;
if (root->val == x) { root->val = y; return; }
if (root->left != NULL) find(root->left, x, y);
if (root->right != NULL) find(root->right, x, y);
}
3.2插入结点操作
注意此时的 root 必须是指针引用,
//插入节点操作,注意此时的 root 必须是指针引用
//指针引用是指针的别名,在函数内部可以修改指针引用指向的地址,以前指向的是a,现在可以在函数内部把他改成指向b;
//传指针是传入参数的一份拷贝,在函数内部修改指针指向的地址,并不会修改原实参所指向的地址。
void insert(Node*& root, int x) {
if (root == NULL) {
root = newNode(x);
return;
}
if (/*看题意要求*/) insert(root->left, x);
else insert(root->right, x);
}
为什么前面的find()
函数不需要对root
加引用呢,因为find()
函数只用来搜索某个二叉树已存在的值并进行修改,只是修改了当前已有节点的内容,所以不需要加引用。
总结: 当修改当前某一已有结点内容或者是遍历树时,不需要加引用。当需要增添一个新的节点这种对二叉树结构作出修改时,需要加引用。
3.3建树操作
通过数组传值和插入操作建立一棵二叉树,没什么好说的。
Node* create(int data[],int n) {
Node* root = NULL;
for (int i = 1; i <= n; i++)
insert(root, data[i]);
return root;
}
3.4删树操作
void delete_tree(Node* root) {
if (root->left != NULL) delete_tree(root->left);
if (root->right != NULL) delete_tree(root->right);
delete(root);
}
基本操作到此为止,可能会有小伙伴要问为什么没有删除节点操作。
第一点,特别复杂,要考虑多种情况,有兴趣的小伙伴可以尝试一下,可以用记录父亲节点的方法来删除。
第二点,没有多大实际意义,一般会在BST用到,会在BST专栏中讲。