7-22 搜索树判断 (25分)(C语言实现)

本文介绍了一种算法,用于判断给定的整数序列是否为二叉搜索树或其镜像树的前序遍历,并通过C语言实现还原树结构,最终输出对应的后序遍历序列。

7-22 搜索树判断 (25分)(C语言实现)

对于二叉搜索树,我们规定任一结点的左子树仅包含严格小于该结点的键值,而其右子树包含大于或等于该结点的键值。如果我们交换每个节点的左子树和右子树,得到的树叫做镜像二叉搜索树。

现在我们给出一个整数键值序列,请编写程序判断该序列是否为某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,如果是,则输出对应二叉树的后序遍历序列。

输入格式:
输入的第一行包含一个正整数N(≤1000),第二行包含N个整数,为给出的整数键值序列,数字间以空格分隔。

输出格式:
输出的第一行首先给出判断结果,如果输入的序列是某棵二叉搜索树或某镜像二叉搜索树的前序遍历序列,则输出YES,否侧输出NO。如果判断结果是YES,下一行输出对应二叉树的后序遍历序列。数字间以空格分隔,但行尾不能有多余的空格。

输入样例1:
7
8 6 5 7 10 8 11

输出样例1:
YES
5 7 6 8 11 10 8

输入样例2:
7
8 6 8 5 10 9 11

输出样例2:
NO

C语言实现

#include<stdio.h>
#include<stdlib.h>
typedef struct node *tree;
struct node{
	int data;
	int flag;
	tree left;
	tree right;
};
int ttp=0,tp=0,fg=1;
tree reTree(tree t,int m);
void myprint(tree t);
tree reteemirror(tree t,int m);
int main(){
	int n,m;
	tree tr=NULL,trm=NULL;
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%d",&m);
		tr=reTree(tr,m);
		trm=reteemirror(trm,m);
	}
	if(ttp==0){//判断搜索树
		printf("YES\n");
		myprint(tr);
	}else if(tp==0){//判断镜子树
		printf("YES\n");
		myprint(trm);
	}else printf("NO\n");
	return 0;
}
//打印后序函数
void myprint(tree t){
	if(t!=NULL){
		myprint(t->left);
		myprint(t->right);
		if(fg==1){
			printf("%d",t->data);
			fg++;
		}else printf(" %d",t->data);
	}
	
}
//还原镜子树
tree reteemirror(tree t,int m){
	if(t==NULL){
		t=(tree)malloc(sizeof(struct node));
		t->left=NULL;
		t->right=NULL;
		t->data=m;
		t->flag=0;
		return t;
	}
	if(t->data <= m && t->flag==0){
		t->left=reteemirror(t->left,m);
	}else{//一旦有了右树枝,就不能在向左树枝插入了,所以有一个flag进行判断
		if(t->data <= m)tp=1;//如果插入的m不符合搜索树的规则就标记
		t->flag=1;
		t->right=reteemirror(t->right,m);
	}
	return t;
}
//还原搜索树
tree reTree(tree t,int m){
	if(t==NULL){
		t=(tree)malloc(sizeof(struct node));
		t->left=NULL;
		t->right=NULL;
		t->data=m;
		t->flag=0;
		return t;
	}
	if(t->data > m && t->flag==0){
		t->left=reTree(t->left,m);
	}else{//一旦有了右树枝,就不能在向左树枝插入了,所以有一个flag进行判断
		if(t->data > m)ttp=1;//如果插入的m不符合二叉树的规则就标记
		t->flag=1;
		t->right=reTree(t->right,m);
	}
	return t;
}

主要思想

这个题主要是对给出搜索树的前序,进行还原树。这个题我主要是对结点进行了:一旦它开始插入右孩子,就再也不对该结点插入左孩子了。所以我用了一个flag经行了标记,标记了的不能插入左孩子,只能插入右孩子。
至于镜子树就更好写了就不多说了。

<think>嗯,用户想找PTA平台上关于C语言实现树结构的题目,特别是7-2的解析或示例代码。首先,我需要确认PTA是什么平台。PTA通常指程序设计类实验辅助教学平台,很多高校用来布置编程题目。用户提到的7-2题可能是一个具体的题目编号,但不同学校可能题目不同,所以直接提供答案可能有困难。 接下来,用户的需求是查找相关题目或代码。由于我无法直接访问PTA平台,可能需要根据常见的树结构题目类型进行推测。常见的树题目包括二叉树的遍历、查找、判断是否为完全二叉树、平衡二叉树等。例如,判断两棵树是否相同、计算树的高度、查找节点等。 用户提到的“查找判断”可能涉及树的查找操作,比如查找某个节点是否存在,或者判断树是否满足某种性质,比如二叉搜索树的条件。7-2题可能涉及这些内容。例如,题目可能要求判断一棵树是否为二叉搜索树,或者查找某个值在树中的路径。 接下来,我需要考虑如何用C语言实现树结构。通常,树的结构体定义包含数据域和左右子树指针。例如: struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; }; 然后,常见的操作包括创建节点、插入节点、遍历(前序、中序、后序)、查找节点、判断树的性质等。比如,判断是否为完全二叉树可能需要层次遍历,并使用队列结构来检查节点是否存在空缺。 用户可能需要示例代码,比如二叉搜索树的查找函数: struct TreeNode* searchBST(struct TreeNode* root, int val) { if (root == NULL || root->data == val) return root; if (val < root->data) return searchBST(root->left, val); else return searchBST(root->right, val); } 或者判断两棵树是否相同的函数: bool isSameTree(struct TreeNode* p, struct TreeNode* q) { if (p == NULL && q == NULL) return true; if (p == NULL || q == NULL) return false; if (p->data != q->data) return false; return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); } 另外,判断是否为二叉搜索树需要中序遍历,并确保每个节点值大于左子树所有节点,小于右子树所有节点。可以用递归方法,或者记录前一个节点的值来比较。 用户可能遇到的具体题目可能要求输入一棵树的结构,然后进行某种判断,比如是否对称、是否平衡等。因此,解析可能涉及如何读取输入构建树,然后应用相应的算法。 需要注意,PTA题目通常有严格的输入输出格式,代码需要处理特定的输入方式,比如层序输入或前序输入。例如,构建二叉树可能需要根据输入的数来递归创建节点,其中-1表示空节点等。 如果用户无法提供具体的题目描述,建议他们查找题目中的关键词,比如“二叉搜索树判断”或“完全二叉树判断”,然后根据常见算法提供思路和代码示例。同时,提醒用户在PTA上提交时注意输入输出的格式要求,避免因为格式错误导致答案错误。 总结来说,用户需要针对PTA平台上的某个树结构题目(7-2)的解析或代码,但由于题目不明确,需给出常见树操作的示例,并建议用户提供更多题目细节以便更准确帮助。同时,引用相关的参考资料,如构造函数调用的场景,可能帮助用户理解C++中vector的行为,但用户的问题是关于C语言的树结构,所以可能引用中的信息不太相关,但需要确认是否有其他引用可用。</think>根据您的需求,我将针对树结构的C语言实现提供通用解题框架和典型示例。由于无法直接访问PTA平台题库,以下内容基于常见树结构考题模式整理。 --- ### 一、树结构实现要点 1. **存储结构**:推荐使用链式存储 ```c typedef struct TreeNode { int data; struct TreeNode *left; struct TreeNode *right; } TreeNode; ``` 2. **核心操作**: - 创建节点:`TreeNode* createNode(int data)` - 插入节点(BST示例): ```c TreeNode* insertBST(TreeNode* root, int data) { if (!root) return createNode(data); if (data < root->data) root->left = insertBST(root->left, data); else root->right = insertBST(root->right, data); return root; } ``` --- ### 二、典型题型解析 #### 场景1:判断二叉树性质 ```c // 判断完全二叉树(层次遍历法) bool isCompleteTree(TreeNode* root) { if (!root) return true; Queue q; // 需自行实现队列 enqueue(q, root); bool hasNull = false; while (!isEmpty(q)) { TreeNode* cur = dequeue(q); if (!cur) { hasNull = true; } else { if (hasNull) return false; enqueue(q, cur->left); enqueue(q, cur->right); } } return true; } ``` #### 场景2:查找特定节点 ```c // 查找最近公共祖先(LCA) TreeNode* LCA(TreeNode* root, TreeNode* p, TreeNode* q) { if (!root || root == p || root == q) return root; TreeNode* left = LCA(root->left, p, q); TreeNode* right = LCA(root->right, p, q); return !left ? right : (!right ? left : root); } ``` --- ### 三、输入输出处理模板 ```c // 构建二叉树示例(输入:前序遍历带空标记) TreeNode* buildTree() { int val; scanf("%d", &val); if (val == -1) return NULL; // -1表示空节点 TreeNode* root = createNode(val); root->left = buildTree(); root->right = buildTree(); return root; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值