统计二叉树中的叶子结点数
时间限制: 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);
}