个人学习编程(3-06) 树形数据结构
返回函数局部变量的指针
思路:
可以申请堆来实现,代码如下:
#include <stdio.h>
using namespace std;
int *func(){
int *p =new int;
*p = 10;
return p;
}
int main() {
int *p1;
p1 = func();
++*p1;
delete p1;
return 0;
}
树的层序建树:
#include <stdio.h>
#include <queue> // 引入queue头文件
using namespace std;
struct TreeNode {
char data;
TreeNode* left;
TreeNode* right;
};
struct QueueNode {
TreeNode* parent;
bool isLeft;
};
void BuildTree(TreeNode*& proot, queue<QueueNode*>& pos, char data) {
if (data != '#') {
// 申请一个新节点
TreeNode* pNew = new TreeNode;
pNew->data = data;
pNew->left = pNew->right = NULL;
// 申请一个队列节点
QueueNode* pQueueNode = new QueueNode;
pQueueNode->parent = pNew;
pQueueNode->isLeft = false;
pos.push(pQueueNode);
if (proot == NULL) {
proot = pNew; // 如果根节点为空,则设置新节点为根节点
} else {
QueueNode* pCur = pos.front(); // 获取队列头部元素
if (pCur->isLeft == false) {
pCur->parent->left = pNew; // 左子节点赋值
pCur->isLeft = true; // 标记为左子节点已赋值
} else {
pCur->parent->right = pNew; // 右子节点赋值
pos.pop(); // 弹出当前节点
delete pCur; // 删除已处理的队列节点
}
}
}
}
int main() {
TreeNode* proot = NULL; // 指向根节点的指针
char data;
queue<QueueNode*> pos; // 队列,用于存储父节点和子节点关系
while (1) {
data = getchar(); // 使用 getchar() 来读取字符
if (data == '\n') {
break; // 如果遇到换行符,结束输入
}
BuildTree(proot, pos, data); // 构建树
}
return 0; // main 函数需要返回 0
}
树的遍历:
void LevelOrder(TreeNode* proot){
queue<TreeNode*> pos;
pos.push(proot);
while (pos.empty() == false){
TreeNode* pCur = pos.front();
pos.pop();
printf("%c",pCur->data);
if(pCur->left != NULL){
pos.push(pCur->left);
}
if (pCur->right != NULL)
{
pos.push(pCur->right);
}
}
printf("\n");
}
树的先序遍历:
void PreOrder(TreeNode* proot) {
if (proot == NULL) {
return;
}
else {
printf("%c", proot->data); // 打印当前节点的数据
PreOrder(proot->left); // 递归遍历左子树
PreOrder(proot->right); // 递归遍历右子树
}
}
树的中序遍历:
void InOrder(TreeNode* proot) {
if (proot == NULL) {
return;
}
else {
InOrder(proot->left); // 递归遍历左子树
printf("%c", proot->data);// 打印当前节点的数据
InOrder(proot->right); // 递归遍历右子树
}
}
树的后序遍历:
void PostOrder(TreeNode* proot) {
if (proot == NULL) {
return;
}
else {
PostOrder(proot->left); // 递归遍历左子树
PostOrder(proot->right); // 递归遍历右子树
printf("%c", proot->data); // 打印当前节点的数据
}
}
树的最短路径:
给定一个n 个结点(编号1~ n)构成的二叉树,其根结点为 1号点,
进行 m 次询问,每次询问两个结点之间的最短路径长度,
树中所有边长均为 1。
输入格式:
第一行包含一个整数 T,表示共有 T 组测试数据。
每组数据第一行包含两个整数 n,m。
接下来” 行,每行包含两个整数,其中第之行的整教表示结点之的子结点编号。如果没有子结点则输出 -1
接下来 m 行,每行包含两个整数,表示要询问的两个结点的编号。输出格式:
每组测试数据输出 m 行,代表查询的两个结点之间的最短路径长度。
1
8 4
2 3
4 5
6 -1
-1 -1
-1 7
-1 -1
8 -1
-1 -1
1 6
2
4 6
4
4 5
2
8 1
4
#include <stdio.h>
#include <vector>
struct TreeNode
{
int num;
TreeNode* left;
TreeNode* right;
TreeNode* parent;
};
using namespace std;
int main() {
int t;
scanf("%d",&t);
for (int i = 0; i < t; i++)
{
int n ,m;
scanf("%d %d",&n,&m);
vector<TreeNode*> nodeArr(n+1);
for (int j = 1; j < n; ++j)
{
nodeArr[j] = new TreeNode;
nodeArr[j]->num = j;
}
nodeArr[1]->parent = NULL;
for (int j = 1; j <= n; ++j)
{
int left,right;
scanf("%d %d",&left,&right);
if (left != -1)
{
nodeArr[j]->left = nodeArr[left];
nodeArr[left]->parent = nodeArr[j];
}
else{
nodeArr[j]->left = NULL;
}
if (right != -1)
{
nodeArr[j]->right = nodeArr[right];
nodeArr[right]->parent = nodeArr[j];
}
else{
nodeArr[j]->right = NULL;
}
}
int lhs,rhs;
for (int j = 0; j < m; ++j)
{
scanf("%d%d",&lhs,&rhs);
vector<int> lvec;
TreeNode* p = nodeArr[lhs];
while (p!=NULL)
{
lvec.push_back(p->num);
p = p->parent;
}
vector<int> rvec;
p = nodeArr[rhs];
while (p != NULL)
{
rvec.push_back(p->num);
p = p->parent;
}
int l = lvec.size()-1;
int r = rvec.size()-1;
while (true)
{
if (l<0 || r<0 || lvec[l] != rvec[r])
{
break;
}
--l;
--r;
}
printf("%d\n",l + r +2);
}
return 0;
}
}