統計二叉樹中的葉子結點數
時間限制: 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);
}