ZOJ-1700 falling leaves

作此题盖练习BST,在调试的过程领会了C指针的博大精深,稍不注意就错,怪不得C++有传引用的特性(VB也有)

鄙人BST动态分配内存,易错啊!!!

小盆友谨慎模仿 :)

CSDN的插入代码插件貌似有点问题,我的一段代码跑到<pre>标签外面了,还得手动改代码...

/*
 * ZOJ 1700 falling leaves
 * mike-w
 * 2011-08-13
 * ----------------------------------------------------
 * BST解此题,刚开始没看懂题目——可能是见了英文有点发懵。
 * 存储数据,逆序建BST。
 */
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#define BUF_SIZE 30

typedef struct _node
{
	char data;
	struct _node* lc;
	struct _node* rc;
}node;

/*
 * creat a new node and initialize
 */
node* cnode(char e)
{
	node* p=(node*)malloc(sizeof(node));
	assert(p);
	p->data=e;
	p->lc=p->rc=NULL;
	return p;
}

/*
 * insert a node in a BST
 * root 是指向根的指针的指针,指针这个搅啊!为了修改根的指针,只能这样...
 */
int insert(node** root,char e)
{
	if(*root==NULL)
		*root=cnode(e);
	else				
	{
		node *p=*root,**pp;
		while(p)						/* 由题意知不存在相等的情况 */
		{								/* 下面的代码风险很高啊		*/
			if(e<p->data)				/* 尤其是我这种一编译error一堆的coder */
				pp=&(p->lc),p=p->lc;	/* 小朋友谨慎模仿 :)		*/
			else
				pp=&(p->rc),p=p->rc;
		}
		*pp=cnode(e);
	}
	return 0;
}

/*
 * traverse a BST in preorder
 * meanwhile destroy it!
 */
int pre(node* root)
{
	node* lc=root->lc;
	node* rc=root->rc;
	putchar(root->data);
	if(lc)
		pre(lc);
	if(rc)
		pre(rc);
	return 0;
}

/*
 * destroy a BST
 * 原来我把先序遍历和删BST放到一起
 * 发现有BUG,有树删不干净的风险!
 * 指针真搅!!!
 */
int destroy(node* root)
{
	node* lc=root->lc;
	node* rc=root->rc;
	free(root);
	if(lc)
		destroy(lc);
	if(rc)
		destroy(rc);
	return 0;
}

int main(void)
{
	node* root;
	char buf[BUF_SIZE][BUF_SIZE];
	int final=0,cnt=0,i,j;
	
#ifndef ONLINE_JUDGE
	freopen("1700.in","r",stdin);
#endif

	while(!final)
	{
		cnt=0;
		root=NULL;
		
		while(scanf("%s",buf[cnt]),(buf[cnt][0]!='*')&&(buf[cnt][0]!='	

	))

				cnt++;

			if(buf[cnt][0]=='

	)

				final=1;

			for(i=cnt-1;i>=0;i--)

				for(j=0;buf[i][j]!='\0';j++)

					insert(&root,buf[i][j]);

			pre(root);

			destroy(root);

			putchar('\n');

		}

		return 0;

	}

	

	

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值