序列化二叉树,二叉搜索树的第K个结点,数据流中的中位数(JZ61-63)C++版本)

#include <iostream>
#include <string>
#include <cstring>
#include <vector>
#include <functional>//less, greater
#include <algorithm>

using namespace std;

struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
		val(x), left(NULL), right(NULL) {
	}
};

class Solution {
public:
	//JZ61 序列化二叉树
	char* Serialize(TreeNode *root);
	void SerializeCore(TreeNode *root, string &result);
	TreeNode* Deserialize(char *str);
	TreeNode* DeserializeCore(char* &str);
	//JZ62 二叉搜索树的第k个结点
	TreeNode* KthNode(TreeNode* pRoot, int k);
	TreeNode* KthNodeCore(TreeNode* pRoot, int &k);
	//JZ63 数据流中的中位数
	void Insert(int num);
	double GetMedian();
private:
	//JZ63 数据流中的中位数
	vector<int> nums1;//大顶堆
	vector<int> nums2;//小顶堆
};

//JZ61 序列化二叉树
char* Solution::Serialize(TreeNode *root) {
	//所有空的'#',包括叶节点的两个子结点
	if (!root)	return nullptr;
	string result;
	SerializeCore(root, result);
	int len = result.size();
	char* temp = new char[len + 1];
	strcpy_s(temp, len + 1, result.c_str());
	return temp;
}
void Solution::SerializeCore(TreeNode *root, string &result) {
	//i指向result的尾部
	if (!root) {
		result.push_back('#');
		result.push_back(',');
		return;
	}
	result += to_string(root->val);
	result.push_back(',');
	SerializeCore(root->left, result);
	SerializeCore(root->right, result);
	return;
}
TreeNode* Solution::Deserialize(char *str) {
	if (!str)	return nullptr;
	TreeNode* result = DeserializeCore(str);
	return result;
}
TreeNode* Solution::DeserializeCore(char* &str) {
	if (*str == ',')	str++;
	if (*str == '#') {
		str++;
		return nullptr;
	}
	if (*str == '\0')	return nullptr;
	int temp = 0;
	while (*str != ',' && *str != '\0') {//二叉树上面的结点有可能是多位数
		temp = 10 * temp + (*str - '0');
		str++;
	}
	TreeNode* result = new TreeNode(temp);
	result->left = DeserializeCore(str);
	result->right = DeserializeCore(str);
	return result;
}
//JZ62 二叉搜索树的第k个结点
TreeNode* Solution::KthNode(TreeNode* pRoot, int k) {
	if (!pRoot || k <= 0)	return nullptr;
	return KthNodeCore(pRoot, k);
}
TreeNode* Solution::KthNodeCore(TreeNode* pRoot, int &k) {
	if (!pRoot)	return nullptr;
	TreeNode* result = nullptr;	
	if (pRoot->left) {
		result = KthNodeCore(pRoot->left, k);
	}
	if (!result) {
		if (k == 1)	result = pRoot;
		k--;
	}
	if (!result && pRoot->right) {
		result = KthNodeCore(pRoot->right, k);
	}
	return result;
}
//JZ63 数据流中的中位数
void Solution::Insert(int num) {
	//两个堆结构,一个是大顶堆,一个是小顶堆
	//将数据流排成一行,左边的是大顶堆,右边的是小顶堆,中位数正好在两个堆顶之间
	if (nums1.size() > 0 && num < nums1[0]) {
		if (((nums1.size() + nums2.size()) & 1) == 0) {//偶数,保证两边的个数之差不大于1
			if (nums1.size() > 0 && nums1[0] > num) {
				nums1.push_back(num);
				push_heap(nums1.begin(), nums1.end(), less<int>());
				num = nums1[0];
				pop_heap(nums1.begin(), nums1.end(), less<int>());
				nums1.pop_back();
			}
			nums2.push_back(num);
			push_heap(nums2.begin(), nums2.end(), greater<int>());
		}
		else {
			if (nums2.size() > 0 && nums2[0] < num) {
				nums2.push_back(num);
				push_heap(nums2.begin(), nums2.end(), greater<int>());
				num = nums2[0];
				pop_heap(nums2.begin(), nums2.end(), greater<int>());
				nums2.pop_back();
			}
			nums1.push_back(num);
			push_heap(nums1.begin(), nums1.end(), less<int>());
		}
	}
}
double Solution::GetMedian() {
	int size = nums1.size() + nums2.size();
	if (size == 0)
		throw "Numbers are invalid";
	double result;
	if ((size & 1) == 1)    result = nums2[0];
	else    result = ((double)(nums1[0] + nums2[0])) / 2;
	return result;
}

//JZ61 序列化二叉树
void test1() {
	TreeNode* pRoot = new TreeNode(1);
	pRoot->left = new TreeNode(2);
	pRoot->left->left = new TreeNode(4);
	pRoot->left->right = new TreeNode(5);
	pRoot->right = new TreeNode(3);
	pRoot->right->left = new TreeNode(6);
	pRoot->right->right = new TreeNode(7);
	Solution s;
	char* result = s.Serialize(pRoot);
	char* temp = result;
	while (*temp != '\0') {
		cout << *temp;
		temp++;
	}
	cout << endl;
	TreeNode* pTemp = s.Deserialize(result);
	return;
}
//JZ62 二叉搜索树的第k个结点
void test2() {
	TreeNode* pRoot = new TreeNode(5);
	pRoot->left = new TreeNode(3);
	pRoot->left->left = new TreeNode(2);
	pRoot->left->right = new TreeNode(4);
	pRoot->right = new TreeNode(7);
	pRoot->right->left = new TreeNode(6);
	pRoot->right->right = new TreeNode(8);
	Solution s;
	cout << s.KthNode(pRoot, 3)->val;
	return;
}


int main() {
	//test1();
	test2();
	//test3();
	//test4();
	system("pause");
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值