二叉树 n叉树 搜索树的各种操作

#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);
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_42189888/article/details/106444749
今日推荐