XDOJ---树

统计二叉树中的叶子结点数

时间限制: 1 秒
内存限制: 256KB

问题描述
建立二叉链表,统计二叉树中的叶子结点数并输出。

输入说明
按照完全二叉树的形式输入二叉树的各结点数据(字符),其中虚结点用’@‘表示。输入以’#'结束。

输出说明
输出叶子结点的个数及具体值。第一行为叶子结点的数据值,各数据用空格分隔,第二行为叶子结点的个数。

输入样例
abc@@de#

输出样例
b d e
3
第一次发现这oj还管超时的,大概叶子的递归太慢了吧(但是上面这题好好的) 这题既建了链树,又递归???
在这里插入图片描述
先把超时代码放上来,个人测试是很完美的

#include<queue>
#include<stdio.h> 
#include<stdlib.h>
using namespace std;
typedef struct TNode *Bintree;
struct TNode{
	char data;
	Bintree left,right;
};
Bintree creat()//enter data until # 
{
	int data;
	Bintree BT,T;
	queue<Bintree> q;
	
	scanf("%c",&data);
	if(data!='#')
	{
		BT=(Bintree)malloc(sizeof(struct TNode));
		BT->data=data;
		BT->left=NULL;BT->right=NULL;
		q.push(BT);
	}
	else return NULL;
	
	
	while(!q.empty())
	{
		T=q.front();
		q.pop();
		scanf("%c",&data);
		if(data=='#') break;
		if(data=='@') T->left=NULL;
		else
		{
			T->left=(Bintree)malloc(sizeof(struct TNode));
			T->left->data=data;
			T->left->left=NULL;T->left->right=NULL;
			q.push(T->left);
		}
		scanf("%c",&data);
		if(data=='#') break;
		if(data=='@') T->right=NULL;
		else
		{
			T->right=(Bintree)malloc(sizeof(struct TNode));
			T->right->data=data;
			T->right->left=NULL;T->right->right=NULL;
			q.push(T->right);
		}
	}
	return BT;
 } 

int cnt=0;//计数:叶子结点个数 全局变量,否则递归的时候每次都会归零
 
void findleave(Bintree T)
{
	if(T)
	{
		if(!T->left&&!T->right)
		{
			printf("%c ",T->data);
			cnt++;
		}
		findleave(T->left);
		findleave(T->right);
	}
}

int main()
{
	Bintree T=creat();
	findleave(T);
	printf("\n%d",cnt);
}

为了不超时,我就只能用树的顺序存储方法了啦啦啦。发现用数组存储真的非常非常方便。
在这里说一下我的思路,因为这个输入数据是个完全完全树,我先把他补成一个满二叉树,把NULL的结点都补成@,那把数组的所有数据都赋值为@就行了(如果还想优化一下的话大概就是算一下有多少数据了,也挺麻烦的,都是线性时间复杂度)
然后数组存数据(注意下标从1开始)
然后每个节点查看他的左儿子和右儿子就行了

#include<stdio.h>

int main()
{
	char tree[1000];
	char ch;
	scanf("%c",&ch);
	int i=1,j,s,cnt=0;
	
	for(j=1;j<1000;j++) //全赋值为@ 
	{
		tree[j]='@';
	}
	
	while(ch!='#')
	{//author:kkzzjx
		tree[i]=ch;
		scanf("%c",&ch);
		i++;
	}
	s=i;
	for(i=1;i<s;i++)
	{
		if(tree[i]!='@'&&tree[i*2]=='@'&&tree[i*2+1]=='@')
		{
			printf("%c ",tree[i]);
			cnt++;
		}
	}
	//author:kkzzjx
	printf("\n%d",cnt);
}

中序遍历二叉排序树

时间限制: 1 秒
内存限制: 256KB

问题描述
输入一整数序列,建立二叉排序树,然后中序遍历。

输入说明
输入第一行为整数的个数n,第二行是具体的n个整数。

输出说明
建立二叉排序树,然后输出中序遍历的结果。

输入样例
5
1 6 5 9 8

输出样例
1 5 6 8 9

#include<stdio.h> 
#include<stdlib.h>
using namespace std;
/*二叉搜索树*/
typedef struct TNode *Bintree;
struct TNode{
	int data;
	Bintree left,right;
}; 

Bintree insert(Bintree BST,int x)
{
	if(!BST)
	{//author:kkzzjx
		BST=(Bintree)malloc(sizeof(struct TNode));
		BST->data=x;
		BST->left=NULL;
		BST->right=NULL;
	}
	else
	{
		if(x<BST->data) BST->left=insert(BST->left,x);
		else if(x>BST->data) BST->right=insert(BST->right,x);
	}
	return BST;
}

void inorder(Bintree t)
{
	if(t)
	{
		inorder(t->left);
		printf("%d ",t->data);
		inorder(t->right);
	}
}


int main()
{
	int n,i,a[1000];
	Bintree BST=NULL;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{//author:kkzzjx
		scanf("%d",&a[i]);
		BST=insert(BST,a[i]);
	}
	inorder(BST);	
}

哈夫曼树

时间限制: 1 秒
内存限制: 256KB

问题描述
假设用于通信的电文由n个字符组成,字符在电文中出现的频度(权值)为w1,w2,…,wn,试根据该权值序列构造哈夫曼树,并计算该树的带权路径长度。

输入说明
第1行为n的值,第2行为n个整数,表示字符的出现频度。

输出说明
输出所构造哈夫曼树的带权路径长度。

输入样例
8
7 19 2 6 32 3 21 10

输出样例
261

思路:
选2个最小的跳出容器,然后和进容器,把和加载wpl值上。
然后啊这,C++最小堆竟然过不了= =
error C2065: “greater”: 未声明的标识符
解决方案:在头文件中加入#include<functional>即可解决

#include<stdio.h>
#include<queue>
#include<functional>
using namespace std;
priority_queue<int ,vector<int> ,greater<int> > q;//最小堆 第三个参数 less<int> 最大堆

int main()
{
	int n,wpl=0,i,t[1000];
	int a,b;
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		scanf("%d",&t[i]);
		q.push(t[i]);
	}
	while(q.size()>=2)
	{
		a=q.top();q.pop();
		b=q.top();q.pop();
		q.push(a+b);
		wpl=wpl+a+b;	
	}
	//author:kkzzjx
	printf("%d",wpl);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章