树的实现

140 阅读5分钟

首先定义一个结构体,包含多个其左节点右节点和父节点的信息

struct TreeNode {
	TreeNode* left = NULL;
	TreeNode* right = NULL;
	TreeNode* parent = NULL;
	long long data = 0;
};

之后实现初始化

TreeNode* init(size_t size) {
	if (size < 1) {
		cout << "ERROR_SIZE" << endl;
		exit(-1);
	}
	/*创建一个指定大小的树,层次遍历法创建,0为根节点*/
	TreeNode** treeNode = new TreeNode* [size];
	treeNode[0] = new TreeNode;
	/*然后实现各个节点的链接*/
	for (size_t i = 1; i < size; i++) {
		if (size == 1)break;
		treeNode[i] = new TreeNode;
		size_t parentPos = (i + 1) / 2 - 1;
		(treeNode[i])->data =(long long)i;
		treeNode[i]->parent = treeNode[parentPos];
		if (2 * (parentPos + 1) == (i + 1))treeNode[parentPos]->left = treeNode[i];
		else treeNode[parentPos]->right = treeNode[i];
	}
	return treeNode[0];
}

这里init()使用数组存节点数据,每个点内的元素为TreeNode*类型,所以要new一个二阶指针 采用层级遍历方式存入数据。实从下标也能发现规律,如果下标从1开始,就使用parentPos = i/2 可以得到父节点,这里从0开始parentPos + 1 = (i + 1) / 2,即size_t parentPos = (i + 1) / 2 - 1

之后就是三种遍历方式(前序,中序,后序)都可以用递推实现

void preOrder(TreeNode* node) {
	/*前序遍历*/
	if (node == NULL) return;
	cout << node->data<<" ";
	preOrder(node->left);
	preOrder(node->right);
}
void inOrder(TreeNode* node) {
	/*中序遍历*/
	if (node == NULL) return;
	inOrder(node->left);
	cout << node->data << " ";
	inOrder(node->right);
}
void lastOrder(TreeNode* node) {
	/*后序遍历*/
	if (node == NULL) return;
	lastOrder(node->left);
	lastOrder(node->right);
	cout << node->data << " ";
}

比较麻烦的是层级遍历,需要用到队列的结构,子节点全部推入,然后输出父节点,如此循环往复直到栈空。 喜欢和野指针打交道的人也可以用数组实现,说的就是c艹

LinkNode** nodeStack(LinkNode** upLevel,size_t level) {
	/*第n层下一层最多有2n个*/
	size_t size =(size_t)pow(2,level + 1);
	LinkNode** nextLevel = new LinkNode*[size];
	for (size_t i = 0; i < size; i++) {
		nextLevel[i] = new LinkNode;
	}
	size_t curPos = 0;
	for (size_t i = 0; i < pow(2, level) && upLevel[i] != NULL; i++) {
		if (upLevel[i]->data->left != NULL) {
			nextLevel[curPos++]->data = upLevel[i]->data->left;
		}
		if (upLevel[i]->data->right != NULL) {
			nextLevel[curPos++]->data = upLevel[i]->data->right;
		}
	}
	if (curPos <size) {
		nextLevel[curPos] = NULL;
	}
	delete upLevel;/*离谱内存管理*/
	return nextLevel;
}

void levelOrder(TreeNode* node) {
	/*层序遍历*/
	if (node == NULL) return;

	LinkNode** root = new LinkNode*[1];
	root[0] = new LinkNode;
	root[0]->data = node;
	LinkNode** nextLevel = root;

	for (int i = 0; ; i++) {
		for (size_t j = 0; j < pow(2,i) && nextLevel[j] != NULL; j++) {
			cout <<nextLevel[j]->data->data << " ";
		}
		nextLevel = nodeStack(nextLevel, i);
		if (nextLevel[0] == NULL) {
			break;
		}
	}
}

之后就层级遍历的方法查找,方法类似

LinkNode* levelFind(TreeNode* node,long long data) {
	if (node == NULL) return NULL;

	LinkNode** root = new LinkNode * [1];
	root[0] = new LinkNode;
	root[0]->data = node;
	LinkNode** nextLevel = root;

	for (int i = 0; ; i++) {
		for (size_t j = 0; j < pow(2, i) && nextLevel[j] != NULL; j++) {
			if (nextLevel[j]->data->data==data) {
				return nextLevel[j];
			}
		}
		nextLevel = nodeStack(nextLevel, i);
		if (nextLevel[0] == NULL) {
			break;
		}
	}
	return NULL;
}

TreeNode* find(TreeNode* node, long long data) {
	LinkNode* linknode = levelFind(node, data);
	if (linknode == NULL) return NULL;
	else return linknode->data;
}

还实现了深度搜索功能,递归实现

size_t deepSerch(TreeNode* node,int level) {
	size_t size = 0 ;
	if (node->left != NULL && node->right != NULL) {
		return size = std::max(deepSerch(node->left, level + 1),deepSerch(node->right, level + 1));
	}
	else if (node->left == NULL && node->right != NULL) {
		return size = deepSerch(node->right, level + 1);
	}
	else if (node->left != NULL && node->right == NULL) {
		return size = deepSerch(node->left, level + 1);
	}
	else {
		return level;
                /*都为空表示.已经到对深的地方了*/
	}
}
size_t maxDepth(TreeNode* node) {
	/*求最大深度,头结点算第一层*/
	if (node == NULL) {
		return 0;
	}
	size_t size = deepSerch(node, 1);
	return size;
}


完全代码实现

#include<iostream>
#include<algorithm>
#include<iomanip>
#include<cmath>
using std::cin;
using std::cout;
using std::endl;

struct TreeNode {
	TreeNode* left = NULL;
	TreeNode* right = NULL;
	TreeNode* parent = NULL;
	long long data = 0;
};

struct LinkNode {
	TreeNode* data;
};

TreeNode* init(size_t size) {
	if (size < 1) {
		cout << "ERROR_SIZE" << endl;
		exit(-1);
	}
	/*创建一个指定大小的树,层次遍历法创建,0为根节点*/
	TreeNode** treeNode = new TreeNode* [size];
	treeNode[0] = new TreeNode;
	/*然后实现各个节点的链接*/
	for (size_t i = 1; i <= size; i++) {
		if (size == 1)break;
		treeNode[i] = new TreeNode;
		size_t parentPos = (i + 1) / 2 - 1;
		(treeNode[i])->data =(long long)i;
		treeNode[i]->parent = treeNode[parentPos];
		if (2 * (parentPos + 1) == (i + 1))treeNode[parentPos]->left = treeNode[i];
		else treeNode[parentPos]->right = treeNode[i];
	}
	return treeNode[0];
}

void destroy(TreeNode* start) {
	if (start->left != NULL)destroy(start->left);
	if (start->right != NULL)destroy(start->right);
	delete start;
	return;
}

void add_left(TreeNode* parent) {
	if (parent->left != NULL)
		cout << "ERROR: LEFT IS OCCUPIED" << endl;
	else {
		TreeNode* treeNode = new TreeNode;
		treeNode->parent = parent;
		parent->left = treeNode;
	}
}
void add_right(TreeNode* parent) {
	if (parent->right != NULL)
		cout << "ERROR: RIGHT IS OCCUPIED" << endl;
	else {
		TreeNode* treeNode = new TreeNode;
		treeNode->parent = parent;
		parent->right = treeNode;
	}
}

void add(TreeNode* parent) {
	/*按照顺序安装左边再安装右边*/
	if (parent->left == NULL)
		add_left(parent);
	else if (parent->right == NULL)
		add_right(parent);
	else cout << "ERROR:BOTH SIDE IS OCCUPIED" << endl;
}

void erase(TreeNode* treeNode) {
	/*删除之后节点以及所有子节点*/
	destroy(treeNode);
}
void reset(TreeNode* node, long long data) {
	if (node == NULL) {
		cout << "ERROR NULL_PTR RESET"<<endl;
		exit(-1);
	}
	node->data = data;
}
void preOrder(TreeNode* node) {
	/*前序遍历*/
	if (node == NULL) return;
	cout << node->data<<" ";
	preOrder(node->left);
	preOrder(node->right);
}
void inOrder(TreeNode* node) {
	/*中序遍历*/
	if (node == NULL) return;
	inOrder(node->left);
	cout << node->data << " ";
	inOrder(node->right);
}
void lastOrder(TreeNode* node) {
	/*后序遍历*/
	if (node == NULL) return;
	lastOrder(node->left);
	lastOrder(node->right);
	cout << node->data << " ";
}
LinkNode** nodeStack(LinkNode** upLevel,size_t level) {
	/*第n层下一层最多有2n个*/
	size_t size =(size_t)pow(2,level + 1);
	LinkNode** nextLevel = new LinkNode*[size];
	for (size_t i = 0; i < size; i++) {
		nextLevel[i] = new LinkNode;
	}
	size_t curPos = 0;
	for (size_t i = 0; i < pow(2, level) && upLevel[i] != NULL; i++) {
		if (upLevel[i]->data->left != NULL) {
			nextLevel[curPos++]->data = upLevel[i]->data->left;
		}
		if (upLevel[i]->data->right != NULL) {
			nextLevel[curPos++]->data = upLevel[i]->data->right;
		}
	}
	if (curPos <size) {
		nextLevel[curPos] = NULL;
	}
	delete upLevel;/*离谱内存管理*/
	return nextLevel;
}

void levelOrder(TreeNode* node) {
	/*层序遍历*/
	if (node == NULL) return;

	LinkNode** root = new LinkNode*[1];
	root[0] = new LinkNode;
	root[0]->data = node;
	LinkNode** nextLevel = root;

	for (int i = 0; ; i++) {
		for (size_t j = 0; j < pow(2,i) && nextLevel[j] != NULL; j++) {
			cout <<nextLevel[j]->data->data << " ";
		}
		nextLevel = nodeStack(nextLevel, i);
		if (nextLevel[0] == NULL) {
			break;
		}
	}
}
size_t deepSerch(TreeNode* node,int level) {
	size_t size = 0 ;
	if (node->left != NULL && node->right != NULL) {
		return size = std::max(deepSerch(node->left, level + 1),deepSerch(node->right, level + 1));
	}
	else if (node->left == NULL && node->right != NULL) {
		return size = deepSerch(node->right, level + 1);
	}
	else if (node->left != NULL && node->right == NULL) {
		return size = deepSerch(node->right, level + 1);
	}
	else {
		return level;
	}
}
size_t maxDepth(TreeNode* node) {
	/*求最大深度,头结点算第一层*/
	if (node == NULL) {
		return 0;
	}
	size_t size = deepSerch(node, 1);
	return size;
}

LinkNode* levelFind(TreeNode* node,long long data) {
	/*层序遍历*/
	/*可以根据返回值连续查找*/
	if (node == NULL) return NULL;

	LinkNode** root = new LinkNode * [1];
	root[0] = new LinkNode;
	root[0]->data = node;
	LinkNode** nextLevel = root;

	for (int i = 0; ; i++) {
		for (size_t j = 0; j < pow(2, i) && nextLevel[j] != NULL; j++) {
			if (nextLevel[j]->data->data==data) {
				return nextLevel[j];
			}
		}
		nextLevel = nodeStack(nextLevel, i);
		if (nextLevel[0] == NULL) {
			break;
		}
	}
	return NULL;
}

TreeNode* find(TreeNode* node, long long data) {
	LinkNode* linknode = levelFind(node, data);
	if (linknode == NULL) return NULL;
	else return linknode->data;
}
int main() {
	TreeNode* t=init(100);
	levelOrder(t);
	cout <<endl<< maxDepth(t)<<endl;
	TreeNode* data = find(t,55);
	cout << data->data << endl;
	reset(data, -100);
	levelOrder(t);
	destroy(t);
}