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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章