wa求助,代码有详细注释
查看原帖
wa求助,代码有详细注释
265218
她是光芒楼主2021/8/30 11:18

大佬帮忙看看,样例过了,自己编了几个样例也没发现错误,但是全wa

#include<bits/stdc++.h>
using namespace std;

typedef struct node {
	int data;
	struct node* lchild;
	struct node* rchild;
	struct node* parent;
	int cnt;	//相同数的个数
}BSTNode, *BSTree;

BSTree insert(BSTree& T, int x)
{
	if (T == NULL) {
		BSTNode* p = (BSTNode*)malloc(sizeof(BSTNode));
		if (p == NULL) {
			printf("内存分配失败!\n");
			return NULL;
		}
		//对p结点赋值操作
		p->data = x;
		p->cnt = 1;	//第一次出现的话就赋1
		p->lchild = NULL;
		p->rchild = NULL;
		return p;
	}
	else {
		if (x < T->data) {	//待插入的数x比当前结点的值小,应插入当前结点左边
			if (T->lchild == NULL) {	//左子树为空的话,直接成为当前结点T的左孩子
				BSTNode* temp = (BSTNode*)malloc(sizeof(BSTNode));
				if (temp == NULL) {
					printf("内存分配失败!\n");
					return false;
				}
				//对temp结点赋值操作
				temp->data = x;
				temp->cnt = 1; //第一次出现的话就赋1
				temp->lchild = NULL;
				temp->rchild = NULL;
				temp->parent = T;	//temp结点的父节点是当前结点T
				T->lchild = temp;	//当前结点T的左孩子是结点temp
			}
			else {	//左子树不为空
				T->lchild = insert(T->lchild, x);	//往左子树中插入x,返回左子树
			}
		}
		else if (x == T->data) {	//已存在x的话,x的个数加一
			T->cnt++;
		}
		else {		//待插入的数x比当前结点的值大,应插入当前结点右边
			if (T->rchild == NULL) {	//右子树为空的话,直接成为当前结点T的右孩子
				BSTNode* temp = (BSTNode*)malloc(sizeof(BSTNode));
				if (temp == NULL) {
					printf("内存分配失败!\n");
					return false;
				}
				//对temp结点赋值操作
				temp->data = x;
				temp->cnt = 1;
				temp->lchild = NULL;
				temp->rchild = NULL;
				temp->parent = T;	//temp结点的父节点是当前结点T
				T->rchild = temp;	//当前结点T的右孩子是结点temp
			}
			else {	//右子树不为空
				T->rchild = insert(T->rchild, x);	//往右子树中插入x,返回右子树
			}		
		}
	}
	return T;
}

void inorder_rank(BSTree T, int x, int& ans)	//中序遍历,ans为x之前的数的个数
{
	if (T == NULL) {
		return;
	}
	//中序遍历
	inorder_rank(T->lchild, x, ans);	
	if (T->data == x) {	//找到x,输出ans+1
		printf("%d\n", ans + 1);
	}
	ans += T->cnt;	//ans加上当前结点值的个数
	inorder_rank(T->rchild, x, ans);
}

int query_rank(BSTree T, int x, int ans)	//查询x的排名,ans为x之前的数的个数
{
	if (T == NULL) {
		return 0;
	}
	inorder_rank(T, x, ans);
	return 0;
}

void inorder_num(BSTree T, int t, int& cur)	//t为排名,cur为小于当前结点值的数的个数
{
	if (T == NULL) {
		return;
	}
	//中序遍历,计算小于当前结点的数的个数
	inorder_num(T->lchild, t, cur);
	if (cur < t && t <= cur + T->cnt)	//如果当前结点的值有多个,且t在范围中
	{
		printf("%d\n", T->data);
	}
	cur += T->cnt;
	inorder_num(T->rchild, t, cur);
}

int query_num(BSTree T, int t)	//查询排名为t的数
{
	int cur = 0;
	if (T == NULL) {
		return 0;
	}
	inorder_num(T, t, cur);
}

BSTree Search(BSTree& T, int i)	//查找值为i的结点
{
	BSTree p = NULL;
	if (T == NULL)
	{
		return NULL;
	}
	if (T->data == i)
	{
		p = T;
	}
	else {
		if (p == NULL)		//还未找到位置(必须用p来判断,否则后续递归,最终结果会是null,覆盖正确位置)
			p = Search(T->lchild, i);
		if (p == NULL)		//同上
			p = Search(T->rchild, i);
	}
	return p;
}

int pre(BSTree& T, int x)
{
	BSTree p = Search(T, x);
	if (p == NULL) {	//树中没有x
		printf("-2147483647\n");
		return NULL;
	}
	else {	
		if (p->lchild != NULL) {	//优先看x的左孩子
			p = p->lchild;
			while (p->rchild != NULL) {
				p = p->rchild;	
			}
			printf("%d\n", p->data);
			return NULL;
		}
		else {	//没有左孩子
			if (p->parent != NULL) {	//看父节点
				printf("%d\n", p->parent->data);
				return NULL;
			}
			else
			{
				printf("-2147483647\n");
				return NULL;
			}		
		}
	}
}

int post(BSTree& T, int x)
{
	BSTree p = Search(T, x);
	if (p == NULL) {
		printf("2147483647\n");
		return NULL;
	}
	else {
		if (p->rchild != NULL) {
			p = p->rchild;
			while (p->lchild != NULL) {
				p = p->lchild;
			}
			printf("%d\n", p->data);
			return NULL;
		}
		else {
			printf("2147483647\n");
			return NULL;
		}
	}
	return 0;
}

int main()
{
	int q, op, x;
	scanf("%d", &q);
	BSTree T = NULL;

	for (int i = 0; i < q; i++) {
		scanf("%d %d", &op, &x);
		switch (op)
		{
		case 1: {
			query_rank(T, x, 0);
			break;
		}
		case 2: {
			query_num(T, x);
			break;
		}
		case 3: {
			pre(T, x);
			break;
		}
		case 4: {
			post(T, x);
			break;
		}
		case 5: {
			T = insert(T, x);
		}
		default:
			break;
		}
	}
	return 0;
}
2021/8/30 11:18
加载中...