#include "pch.h"
#include<cstdio>
#include<string>
#include<queue>
using namespace std;
struct node {//二叉树的节点
int data;
int layer;//所在层次
node* lchild;
node* rchild;
};
node* newNode(int v) {//建立二叉树的新节点
node* Node = new node;
Node->data = v;
Node->lchild = Node->rchild = NULL;
return Node;
}
void search(node* root, int x, int newData) {//查找与修改
if (root == NULL) return;
if (root->data == x) root->data = newData;
search(root->lchild, x, newData);
search(root->rchild, x, newData);
}
//在二叉树中插入一个数据域为x的新节点
//注意根节点指针root要使用引用,否则插入不成功
void insert(node* &root, int x) {
if (root == NULL) {//空树,说明查找失败,也即插入位置
root = newNode(x);
return;
}
insert(root->lchild, x);
insert(root->rchild, x);
}
//创建二叉树
node* Create(int data[], int n) {
node* root = NULL;
for (int i = 0; i < n; i++) {
insert(root, data[i]);
}
return root;
}
//先序遍历 特点:序列的第一个节点是根节点
void preorder(node* root) {
if (root == NULL) return;
//访问根节点root
printf("%d\n", root->data);
//访问左子树
preorder(root->lchild);
//
preorder(root->rchild);
}
//中序遍历 特点:序列中知道根节点之后,就能知道左右子树了
void inorder(node* root) {
if (root == NULL) return;
inorder(root->lchild);
printf("%d\n", root->data);
inorder(root->rchild);
}
//后序遍历 特点:序列的最后一个是根节点
void postorder(node* root) {
if (root == NULL) return;
postorder(root->lchild);
postorder(root->rchild);
printf("%d\n", root->data);
}
//层次遍历
void layerorder(node* root) {
queue<node*> q;
root->layer = 1;
q.push(root);
while (!q.empty()) {
node* now = q.front();
q.pop();
printf("%d\n", now->data);
if (now->lchild != NULL) {
now->lchild->layer = now->layer + 1;
q.push(now->lchild);
}
if (now->rchild != NULL) {
now->rchild->layer = now->layer + 1;
q.push(now->rchild);
}
}
}
//根据中序遍历和先序遍历重建二叉树
int pre[] = { 5,2,4,1,3 };
int in[] = { 2,4,1,3,5 };
node* createby(int preL, int preR, int inL, int inR) {
if (preL > preR) return NULL;//先序序列长度小于0直接返回
node* root = new node;
root->data = pre[preL];// 新节点的数据域为根节点的值
int k;
for (k = inL; k < inR; k++) {
if (in[k] == pre[preL]) break;//在中序序列中找根节点
}
int numLeft = k - inL;//左子树节点个数
//左子树的先序遍历区间为[preL+1,preL+numleft] 中序遍历区间为[inL,k-1]
root->lchild = createby(preL + 1, preL + numLeft, inL, k - 1);
root->rchild = createby(preL + numLeft + 1, preR, k + 1, inR);
return root;
}
一般树:
const int maxn = 1000;
struct node {
int data;//数据域
vector<int> child;//指针域,存放所有子节点下标
int layer;
}Node[maxn];
//创建新节点
int index = 0;
int newNode(int v) {
Node[index].data = v;
Node[index].child.clear();
return index++;
}
//树的先根遍历
void preOeder(int root) {
cout << Node[root].data;
for (int i = 0; i < Node[root].child.size(); i++) {
preOeder(Node[root].child[i]);//递归访问所有子节点
}
}
//树的层次遍历
void LayerOrder(int root) {
queue<int> q;
q.push(root);
while (!q.empty()) {
int front = q.front();
q.pop();
cout << Node[front].data;
for (int i = 0; i < Node[front].child.size();i++) {
int child = Node[front].child[i];
Node[child].layer = Node[front].layer + 1;
q.push(Node[front].child[i]);//所有子节点入队
}
}
}
二叉搜索树:
const int maxn = 1000;
struct node {
int data;//数据域
node* lchild;
node* rchild;
};
node* newNode(int v) {//建立二叉树的新节点
node* Node = new node;
Node->data = v;
Node->lchild = Node->rchild = NULL;
return Node;
}
//查找二叉查找树中数据域为x的节点
void search(node* root, int x) {
if (root == NULL) {
printf("search failed\n");
return;
}
if (x == root->data) {
printf("%d\n", root->data);
}
else if (x < root->data) {
search(root->lchild, x);
}
else {
search(root->rchild, x);
}
}
//插入操作
void insert(node* &root, int x) {
if (root == NULL) {
//空树说明查找失败,也即插入位置
root = newNode(x);
return;
}
if (x == root->data) {
//节点已存在,返回
return;
}
else if (x < root->data) {
insert(root->lchild, x);
}
else {
insert(root->rchild, x);
}
}
//二叉查找树的建立
node* create(int data[], int n) {
node* root = NULL;
for (int i=0; i < n; i++) {
insert(root, data[i]);
}
return root;
}
//删除节点:
node* findMax(node* root) {
while (root->rchild) {
root = root->rchild;
}
return root;
}
node* findMin(node*root) {
while (root->rchild) {
root = root->rchild;
}
return root;
}
void deleteNode(node* &root, int x) {
if (root == NULL)return;//不存在权值为x的节点
if (root->data == x) {
if (root->lchild == NULL && root->rchild == NULL) {
root = NULL;//叶子节点的话直接删除
}
else if (root->lchild) {
//左不为空
node* pre = findMax(root->lchild);//找root前驱
root->data = pre->data;//用前驱覆盖root
deleteNode(root->lchild, pre->data);//删除节点pre
}
else {
//右不为空
node* next = findMin(root->rchild);
root->data = next->data;
deleteNode(root->rchild, next->data);
}
}
else if (root->data > x) {
deleteNode(root->lchild, x);
}
else {
deleteNode(root->rchild, x);
}
}