您的位置:首页 > 编程语言 > C语言/C++

C语言经典题目及解题思路

2009-07-28 15:40 375 查看
1、

【问题描述】梯有N阶,上楼可以一步上一阶,也可以一步上二阶。编写一个程序,计算共有多少中不同的走法

【思路】看到此题目容易想到用递归的方法来做,因为递归是一种描述和解决结构自相似问题的基本算法,而N阶楼梯问题和N-1阶、N-2阶的结构完全相同。

解决递归问题可以分为两个部分,第一部分是一些特殊(基础)情况,用直接法解,即始基;第二部分与原问题相似,可用类似的方法解决(即递归),但比原问题的规模要小。

定义int count(int n)函数求解N阶楼梯的走法,基于上述思想,可知:

N阶楼梯问题的始基是N==1、N==2两种情况;

上楼可以一步上一阶,也可以一步上二阶,当上一阶时问题规模变为N-1,当上二阶时问题规模变为N-2,所以总的情况为count(n-1)+count(n-2)。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int count(int n);

/*count how many ways to climb up N steps stairs.*/

int main (int argc, char *argv[])

{

int n,ct;

printf("please input n:/n");

scanf("%d",&n);

ct=count(n);

printf("there are %d ways to climb up N steps stairs!/n",ct);

system("PAUSE");

return 0;

}

int count(int n)

{

if(1==n)

return 1;

else if(2==n)

return 2;

else return count(n-1)+count(n-2);

}
【程序输入输出】for example

please input n:

5

there are 8 ways to climb up N steps stairs!

2、

【问题描述】Armstrong数具有如下特征:一个n位数等于其个位数的n次方之和。如:

153=1^3+5^3+3^3

1634=1^4+6^4+3^4+4^4

找出2、3、4、5位的所有Armstrong数。

【思路】看到此题我第一反应是用枚举法,给定m(10<=m<=99999),首先判断m的位数n,然后判断它是否等于各位数的n次方之和。

定义函数int judgeDigit(int m),用于判断给定参数m的位数;

定义函数int judgeEqual(int m,int n),其中m为给定的数,n为m的位数,用于判断m是否等于各位数的n次方之和。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

int judgeDigit(int m);

/*This function return the digit of parameter m*/

void judgeEqual(int m,int n);

/*parameter m is a integer,parameter n is the digit of m,this function
is used to judge m whether is a Armstrong integer and output it*/

int main (int argc, char **argv)

{

int i,len;

printf("All 2 digit to 5 digit Armstrong integers are following:/n");

for(i=10;i<=99999;i++)

{

len=judgeDigit(i);

judgeEqual(i,len);

}

printf("/n");

system("PAUSE");

return 0;

}

int judgeDigit(int m)

{/*This function return the digit of parameter m*/

int len=0;

do

{

++len;

m=m/10;

}while(m);

return len;

}

void judgeEqual(int m,int n)

{/*parameter m is a integer,parameter n is the digit of m,this function
is used to judge m whether is a Armstrong integer and output it*/

int j,temp=m,sum=0;

for(j=1;j<=n;j++)

{

sum+=(int)(pow(temp%10,n));

temp=temp/10;

}

if(m==sum)/*if m is equal to sum,that is to say m is a Armstrong integer*/

printf("%d/t",m);

}

【程序输入输出】

no input;

output:

All 2 digit to 5 digit Armstrong integers are following:

153
370 371 407 1634 8208 9474 54748 92727 93084

注:用gcc调试就得不到153这个结果,但windows下用vc6.0就可以得到。不解中,这是编译器问题还是程序问题?

3、

【问题描述】将1,2,3,4,5,6,7,8,9共9个数分成三组,组成3个三位数,且使这3个三位数构成1:2:3的比例,例如:3个三位数192,384,576满足以上条件.192:384:576=1:2:3。试求出所有满足条件的3个三位数。

【思路】1~9组成的最小三位数是123,最大的是987,由于要满足1:2:3的关系,最小的那个数应该不到于987/3=329。这样的话第一个数的
变化范围是123~329,将这里面的数分别乘2、乘3,然后判断这三个数是否符合要求,即这三个数是否由1~9组成,而且各个数字不能相同。

即对每个数n(123<=n<=329)用枚举法。

定义函数int judge(int n),用于判断整数n的各位数字是否相同,如果有想同的就返回0;否则返回1;

对每个数n(123<=n<=329),2*n,3*n调用judge()函数用于判断这三个数是否由1~9组成且各个数字不相同;

判断n,2*n,3*n这三个数中的各位数是否相同,所以对数n*1000*1000+2*n*1000+3*n调用judge()判断。

所以(judge(n)==0||judge(2*n)==0||judge(3*n)==0||judge(n*1000+2*n*100+3*n)==0)为真的话,即其中给定的n不符合要求。其实只要(
judge(n*1000+2*n*100+3*n)==0)这一个条件即可,因为它包含了前面两种情况。

  caution:其实要判断这三个数是否由1~9组成且各个数组不相同,即这三个数的各位数是否覆盖了1~9,只要判断各位数字的积是否等于9!且各位数字的和是否等于45。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int judge(int n);

int main (int argc, char **argv)

{

int l,m,n,p,q;

for(l=123;l<=329;l++)

{

m=2*l,n=3*l;

p=l*1000+m,q=p*1000+n;

if(judge(q)==0)

//判断l、m、n是否符合要求。如果不符合就跳出本次循环,进入下次循环

continue;

printf("%d,%d,%d/n",l,m,n);

}

system("PAUSE");

return 0;

}

int judge(int n)

{//用于判断整数n的各位数字是否相同,如果有想同的就返回0;否则返回1

int num[10],i,j,len=0,temp=n;

do

{

++len;

temp=temp/10;

}while(temp);//求出n的位数

for(i=1;i<=len;i++)

{//将n的各位数字存入num[],并判断是否存在0及相同的数字,如果存在就返回0

if((num=n%10)==0)

return 0;

n=n/10;

for(j=1;j<i;j++)

if(num[j]==num)

return 0;

}

return 1;

}
cCODE:来自一位网友youshuang

,即用判断各位数字的积是否等于9!且各位数字的和是否等于45。

)

#include <stdio.h>

bool judge( int a, int b, int c )

{

char tmp_buf[ 10 ];

sprintf( tmp_buf, "%d%d%d", a, b, c );

int nTimeResult = 1;

int nSumResult = 0;

for ( int i = 0; i < 9; i++ )

{

nTimeResult *= ( tmp_buf[ i ] - '0' );

nSumResult += ( tmp_buf[ i ] - '0' );

}

return ( ( nTimeResult == 362880 ) && ( nSumResult == 45 ) );

}

int main()

{

for ( int i = 123; i <= 329; i++ )

{

if ( judge( i, i * 2, i * 3 ) )

{

printf( "%d, %d, %d /n", i, i * 2, i * 3 );

}

}

return 0;

}
【程序输入输出】

no input;

output:

192,384,576

219,438,657

273,546,819

327,654,981

4、

【问题描述】和尚挑水

某寺庙里7个和尚:轮流挑水,为了和其他任务不能冲突,各人将有空天数列出如下表:

和尚1: 星期二,四;

和尚2: 星期一,六;

和尚3: 星期三,日;

和尚4: 星期五;

和尚5: 星期一,四,六;

和尚6: 星期二,五;

和尚7: 星期三,六,日;

请将所有合理的挑水时间安排表

【思路】用回朔法求解(递归方式实现,当然也可以用迭代方式)。用结构体存储和尚的信息(空闲时间、是否已经挑过水标记)回朔法即每进行一步,都试图在当
前部分解的基础上扩大该部分解。扩大时,首先检查扩大后是否违反了约束条件,若不违反,则扩大之,然后继续在此基础上按照类似的方法进行,直至成为完整
解;若违反,则放弃该步以及它所能生成的部分解,然后按照类似的方法尝试其他可能的扩大方式,直到尝试了所有的扩大方式。  

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

void backtrack(int n);

/*函数功能:回朔求解第n天至第7天的解(即第n~7天分别安排和尚几)*/

struct st

{

int spare[8];

/*存储和尚的空闲时间,spare=0表示星期i没有空闲,spare=1表示星期i空闲,其中spare[0]不用*/

int flag;

/*用于标记和尚周内是否已经工作过,flag=0表示没挑过水,flag=1表示已经挑过水*/

}monk[8];

int x[8],sum=0;/*sum用于统计共有多少种方案*/

int main (int argc, char **argv)

{

int i,j;

for(i=1;i<=7;i++)

{/*初始化和尚的空闲时间,初始化时和尚全部没挑过水即flag都为0*/

printf("请输入和尚%d的空闲时间:",i);

for(j=1;j<=7;j++)

{

scanf("%d",&monk.spare[j]);

}

monk.flag=0;

}

backtrack(1);

printf("共有%d种方案/n",sum);

}

void backtrack(int n)

{/*函数功能:回朔求解第n天至第7天的解(即第n~7天分别安排和尚几)*/

int j;

if(n>7)

{

sum++;

printf("方案%d:/n",sum);

for(j=1;j<=7;j++)

{

printf("星期%d和尚%d挑水/n",j,x[j]);

}

printf("/n");

}

else

{

for(j=1;j<=7;j++)

{

x
=j;

if(monk[j].flag==0&&monk[j].spare
==1)

{//判断和尚j是否已经挑过水及和尚星期n是否有空

monk[j].flag=1;

backtrack(n+1);

monk[j].flag=0;

}

}

}

}
【程序输入输出】

input:

请输入和尚1的空闲时间:0 1 0 1 0 0 0

请输入和尚2的空闲时间:1 0 0 0 0 1 0

请输入和尚3的空闲时间:0 0 1 0 0 0 1

请输入和尚4的空闲时间:0 0 0 0 1 0 0

请输入和尚5的空闲时间:1 0 0 1 0 1 0

请输入和尚6的空闲时间:0 1 0 0 1 0 0

请输入和尚7的空闲时间:0 0 1 0 0 1 1

output:

方案1:

星期1和尚2挑水

星期2和尚6挑水

星期3和尚3挑水

星期4和尚1挑水

星期5和尚4挑水

星期6和尚5挑水

星期7和尚7挑水

方案2:

星期1和尚2挑水

星期2和尚6挑水

星期3和尚7挑水

星期4和尚1挑水

星期5和尚4挑水

星期6和尚5挑水

星期7和尚3挑水

方案3:

星期1和尚5挑水

星期2和尚6挑水

星期3和尚3挑水

星期4和尚1挑水

星期5和尚4挑水

星期6和尚2挑水

星期7和尚7挑水

方案4:

星期1和尚5挑水

星期2和尚6挑水

星期3和尚7挑水

星期4和尚1挑水

星期5和尚4挑水

星期6和尚2挑水

星期7和尚3挑水

共有4种方案

5、

【问题描述】编写一个
c程序,利用如下的格里高利公式求
п的值,直到最后一项的值小于
10-6为止。



【思路】由公式可以看出,



每次
n的值都会改变,这实际上就是迭代。

在程序设计中,迭代是经常使用的一种算法。使用迭代算法时要注意三个问题:

迭代的初始值,如本题中
sum的初始值为
1,
n的初始值为
1

迭代公式,这是迭代的关键,如果有几个迭代公式,要特别注意这些迭代的顺序。如
i+=1和
sum+=n的次序不能交换。

迭代终止条件。一般用一个表达式或者计数器来判断迭代式是否应该终止。

本题中迭代式中
i+=1,
i的初始值为
1;



sum+=n or sum-=n这通过一个标志变量
flag来控制,
flag==1时
sum+=n,
flag==0时
sum-=n,
sum的初始值为
1。终止条件为





【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

#include<math.h>

int main (int argc, char **argv)

{

int flag=0,i=1;

double n=1,sum=1;

while(n>=pow(10,-6))

{

n=(double)1/(2*i+1);

i+=1;

if(1==flag)

{

sum+=n;

flag=0;

}

else

{

sum-=n;

flag=1;

}

}

sum*=4;

printf("%lf",sum);

system("PAUSE");

return 0;

}

【程序输入输出】

No input;

Output:

3.141595

6、

【问题描述】编写一个
c程序,把下列数组延长到第
50项:

1,
2,
5,
10,
21,
42,
85,
170,
341,
682

【思路】由给定的数组元素可以看出偶数项是前一项的
2倍,奇数项是前一项的
2倍加
1。





,这是一中递推关系由前项推出后项,此题可以通过递推关系求解。

递推解题和迭代解题是很相似的,递推是通过其他变量来演化,而迭代则是通过自身不断演化。递推法的运用也有三个关键:

寻找递推关系。这是最重要的问题。递推关系有解析和非解析两种。解析递推关系是指能用一般数学公式描
述的关系,也称递推公式。例如,本题的递推关系就是解析的。非解析递推关系是指不能用一般的数学公式描述的关系,这类关系的描述,也许本身就是一个过程。
这类问题一般比较复杂,要结合其他的策略如分治法来解决。

递推关系必须有始基,即最小子解(针对初始规模的子解的值),没有始基,递推计算就不能开始。例如本题
a1=1就是始基。

递推计算。即根据递推关系进行递推计算。递推计算可以由递归解析和非递归两种,递归计算是采用递归法,其形式是自顶向下,而非递归则是自底向上。本题是非递归的。

解此题还须注意一点:数列的项必须定义为
double型,因为延长到第
50项如果定义为
int or float型,数列的项会被截断即超过
int和
float的表示范围。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int main (int argc, char **argv)

{

double a1=1,a=0;

int i=1;

while(i<=50)

{

printf("%.0lf ",a1); //'.0’ is just for do not output the decimal place

i++;

if(i%2==1)

a=2*a1+1;

else

a=2*a1;

a1=a;

}

system("PAUSE");

return 0;

}

【程序输入输出】

No input;

Output:

1 2 5 10 21 42 85 .......(略)

7、

【问题描述】 用递归算法实现求一个数组中的最大元素。

【思路】解决递归问题可以分为两个部分,第一部分是一些特殊(基础)情况,用直接法解,即始基;第二部分与原问题相似,可用类似的方法解决(即递归),但比原问题的规模要小。

本题显然始基是a[0],关键是要找出递归关系,定义一个函数int max(int a[],int n),其中整型a[]是一个数组,n是数组长度减1,即数组最大有效元素的下标,因为c语言中数组元素下标是从0开始的。



如果0==n,则a[0]就是最大的元素

如果n>0,则先求出a[0]到a[n-1]的最大元素,然后与a
比较,较大者即为最大元素。其中a[0]到a[n-1]又可以用这种方式求,此时需要将a[0],a[1]...a[n-1]看成一个由n-1个元素构成的一维数组。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int max(int a[],int n);

int main (int argc, char **argv)

{

int a[]={1,2,3,4,5,6,7,6};

printf("The max element is %d!/n",max(a,7));

/*caution:he length of a is 8,but the argument is 7*/

system("PAUSE");

return 0;

}

int max(int a[],int n)

{

if(0==n)

return a
;

else

return (a
>max(a,n-1)?a
:max(a,n-1));

}

【程序输入输出】

no input;

output:

The max element is 7!

8、

【问题描述】自然数的拆分:任何一个大于1的自然数N,总可以拆分成若干个自然数之和,并且有多种拆分方法。例如自然数5,可以有如下一些拆分方法:

5=1+1+1+1+1

5=1+1+1+2

5=1+2+2

5=1+4

5=2+3

【思路】自然数的拆分可以用回溯法。

知识点



溯法解题时,对任一解的生产,一般采用逐步扩大解的方式。每进行一步,都试图在当前部分解的基础上扩大该部分解。扩大时,首先检查扩大后是否违反了约束条
件,若不违反,则扩大之,然后继续在此基础上按照类似的方法进行,直至为完全解;若违反,则放弃该步以及它生成的部分解,然后按照类似的方法尝试其他可能
的扩大方式,直到已经尝试了所有的扩大方式。

回溯法解题通常包含以下三个步骤:

针对所给问题,定义问题的解空间;如本题对
5的拆分来说,
1<=拆分的数
<=5。

确定易于搜索的解空间结构;如本题对
5的拆分来说,用
x[]数组来存储解,每个数组元素的取值范围都是
1<=拆分的数
<=5,从
1开始搜索直到
5。

搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。如本题对
5的拆分来说,为了避免重复,
x>=x[j](i>j),如
x[]={2,3}满足条件而
x[]={3,2}就不满足条件不是可行解即无效。

回溯法通常有两种实现方式,一种是递归的方式,另一种是迭代的方式。在此就用递归方式,当然迭代的方式也可以。
  

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

void splitN(int n,int m);//n是需要拆分的数,
m是拆分的进度。

int x[1024]={0},total=0 ;//total用于计数拆分的方法数,
x[]用于存储解

int main()

{

int n ;

printf("please input the natural number n:");

scanf("%d",&n);

splitN(n,1);

printf("There are %d ways to split natural number %d./n",total,n);

system("PAUSE");

return 0 ;

}

void splitN(int n,int m)

{//n是需要拆分的数,
m是拆分的进度。

int rest,i,j;

for(i=1;i<=n;i++)

{//从
1开始尝试拆分。

if(i>=x[m-1])

{//拆分的数大于或等于前一个从而保证不重复

x[m]=i ;//将这个数计入结果中。

rest=n-i ;//剩下的数是
n-i,如果已经没有剩下的了,并且进度
(总的拆分个数
)大于
1,说明已经得到一个结果。

if(rest==0&&m>1)

{

total++;

printf("%d/t",total);

for(j=1;j<m;j++)

{

printf("%d+",x[j]);

}

printf("%d/n",x[m]);

}

else

{

splitN(rest,m+1);//否则将剩下的数进行进度为
m+1拆分。

}

x[m]=0;//取消本次结果,进行下一次拆分。环境恢复,即回溯

}

}

}
【程序输入输出】

input:

please input the natural number n:5

output:

1 1+1+1+1+1

2 1+1+1+2

3 1+1+3

4 1+2+2

5 1+4

6 2+3

There are 6 ways to split natural number 5.

9、

【问题描述】用递归函数求解两个正整数的最大公约数的过程。

【思路】此题不需太多的思考就是运用欧几里得算法(
Euclid’s algorithm)。

摘自《
The Art of Computer Programming》
volume 1:

(Euclid’s algorithm )Give two postive integers m and n, find their
greatest common divisor, that is ,the largest positive integer that
evenly divide both m and n.

Step1.[Find remainder.]Divide m by n and let r be the remainder.(We will have 0<=r<n.)

Step2.[Is it zero?]If r=0,the algorithm terminates; n is the answer.

Step3.[Reduce.]Set m=n,n=r, and go back to Step1.

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int GCD(int m,int n);

/*function is to find the greatest common divisor between mand n*/

int main (int argc, char **argv)

{

int m,n,temp;

printf("Please input m and n:/n");

scanf("%d %d",&m,&n);

if(m<n)

{/*This is just ensure m>n*/

temp=m;

m=n;

n=temp;

}

printf("The greatest common divisor of (%d,%d) is %d!/n",m,n,GCD(m,n));

system("PAUSE");

return 0;

}

int GCD(int m,int n)

{

if(m%n==0)

return n;

else return GCD(n,m%n);

}

【程序输入输出】

Please input m and n:

10 5

The greatest common divisor of (10,5) is 5!

10、

【问题描述】 已知Ackerman函数对于整数m>=0和n>=0有如下定义:

ack(0,n)=n+1

ack(m,0)=ack(m-1,1)

ack(m,n)=ack(m-1,ack(m,n-1))

【思路】此题明显用递归方法解,由上述定义可得递归公式如下:

| n+1,

当m=0时;

ack(m,n)= | ack(m-1,1),

当n=0时;

| ack(m-1,ack(m,n-1)),

其他情况。

【代码】

cCODE:

#include<stdio.h>

#include<stdlib.h>

int ack(int m,int n);

int main (int argc, char **argv)

{

int m,n;

printf("Please input m and n:/n");

scanf("%d %d",&m,&n);

printf("The result of ack(%d,%d) is %d!/n",m,n,ack(m,n));

system("PAUSE");

return 0;

}

int ack(int m,int n)

{

if(0==m)

return n+1;

else if(0==n)

return ack(m-1,1);

else return ack(m-1,ack(m,n-1));

}

【程序输入输出】

example 1:

input:

Please input m and n:

0 5

ouput:

The result of ack(0,5) is 6!

example 2:

Please input m and n:

4 0

The result of ack(4,0) is 13!

example 3:

Please input m and n:

2 3

The result of ack(2,3) is 9!

//------------------------------------------------------------------------------------//

1、线形表a、b为两个有序升序的线形表,编写一程序,使两个有序线形表合并成一个有序升序线形表h;

[Copy to clipboard]
[ -
]

CODE:
#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

#define QUIT 999

typedef struct node

{

int num;

struct node* next;

}NODE;

int create_list(NODE** head)

{

int num;

int i = 0;

NODE* p = NULL;

NODE* q = NULL;

*head = (NODE*)malloc(sizeof(NODE));

if(*head == NULL)

{

printf("head malloc error/n");

return -1;

}

(*head)->next = NULL;

printf("input %d to end add list/n",QUIT);

while(1)

{

p = *head;

q = (NODE*)malloc(sizeof(NODE));

if(q == NULL)

{

printf("head malloc error/n");

return -1;

}

i++;

printf("Now Please input num %d:/t",i);

scanf("%d",&num);

if(num == QUIT)

{

printf("end create list/n");

break;

}

q->num = num;

while((p->next != NULL) && (p->next->num < num))

{

p = p->next;

}

q->next = p->next;

p->next = q;

}

return 0;

}

NODE* merge_list(NODE* head1,NODE* head2)

{

assert(head1 != NULL);

assert(head2 != NULL);

NODE* head = (NODE*)malloc(sizeof(NODE));

if(head == NULL)

{

printf("head malloc error/n");

return NULL;

}

NODE* head_tmp = head;

NODE* p1 = head1->next;

NODE* p2 = head2->next;

while((p1 != NULL) && (p2 != NULL))

{

printf("p1 data is %d/t p2 date is %d/n",p1->num,p2->num);

if(p1->num < p2->num)

{

printf("copied %d/n",p1->num);

system("PAUSE");

head_tmp->next = p1;

p1 = p1->next;

}

else

{

printf("copied %d/n",p2->num);

system("PAUSE");

head_tmp->next = p2;

p2 = p2->next;

}

head_tmp = head_tmp->next;

}

if(p1 == NULL)

{

head_tmp->next = p2;

printf("asdas copied:/n");

print_list(head_tmp);

}

else

{

head_tmp->next = p1;

printf("asdas copied:/n");

print_list(head_tmp);

}

return head;

}

int print_list(NODE* head)

{

assert(head != NULL);

NODE* p = head;

while(p->next != NULL)

{

printf("%d/t",p->next->num);

p = p->next;

}

printf("/n");

}

int main(int argc, char *argv[])

{

NODE* head1 = NULL;

NODE* head2 = NULL;

create_list(&head1);

create_list(&head2);

printf("list1 is:/n");

print_list(head1);

printf("list2 is:/n");

print_list(head2);

printf("merged list is:/n");

print_list(merge_list(head1,head2));

system("PAUSE");

return 0;

}

2编写算法,从10亿个浮点数当中,选出其中最大的10000个。

[Copy to clipboard]
[ -
]

CODE:
#include <stdio.h>

#include <stdlib.h>

#include <time.h>

//#define INIT 10000

#define INIT 5

//#define TOTAL 100000000

#define TOTAL 10

static int count = 0;

typedef struct tree

{

int num;

struct tree* parent;

struct tree* lchild;

struct tree* rchild;

}TREE;

TREE* add_tree(TREE** T, TREE* parent, int num)

{

if(*T == NULL)

{

*T = (TREE*)malloc(sizeof(TREE));

if(*T == NULL)

{

printf("malloc error/n");

return NULL;

}

printf("added %d/n",num);

(*T)->num = num;

(*T)->parent = parent;

(*T)->lchild = NULL;

(*T)->rchild = NULL;

}

else if((*T)->num < num)

return add_tree(&(*T)->rchild,*T,num);

else

return add_tree(&(*T)->lchild,*T,num);

}

int midwalk(TREE* T)

{

if(T!=NULL)

{

midwalk(T->lchild);

count++;

if(count%10 == 0)

{

count = 0;

printf("%d/n",T->num);

}

else

printf("%d/t",T->num);

midwalk(T->rchild);

}

return 0;

}

int tree_out(TREE** T)

{

int num = 0;

TREE* p = NULL;

TREE* q = NULL;

TREE** tmp = T;

TREE* tmp1 = *T;

printf("tmp is %p/ntmp1 is %p/n",*tmp,tmp1);

if(*tmp == NULL)

{

printf("sorry the tree is empty/n");

return -1;

}

if((*tmp)->lchild == NULL)

{

q = *tmp;

num = q->num;

*tmp = (*tmp)->rchild;

printf("now head is %d/n",q->num);

free(q);

q = NULL;

return num;

}

#if 1

while(tmp1->lchild != NULL)

{

p = tmp1;

tmp1 = tmp1->lchild;

}

p->lchild = tmp1->rchild;

num = tmp1->num;

free(tmp1);

#endif

#if 0

while((*tmp)->lchild != NULL)

{

p = *tmp;

*tmp = (*tmp)->lchild;

}

p->lchild = (*tmp)->rchild;

num = (*tmp)->num;

free(*tmp);

#endif

return num;

}

int minimum(TREE* T)

{

while(T->lchild != NULL)

{

T = T->lchild;

}

return T->num;

}

int main(int argc, char *argv[])

{

int i = 0;

int num = 0;

double j = INIT;

int mini = 0;

TREE* T = NULL;

srand( (unsigned)time( NULL ) );

for(i=0;i<INIT;i++)

{

num = rand();

add_tree(&T, NULL, num);

}

midwalk(T);

mini = minimum(T);

for(j=INIT;j<TOTAL;j++)

{

num = rand();

if(num > mini)

{

tree_out(&T);

add_tree(&T, NULL, num);

mini = minimum(T);

}

}

midwalk(T);

system("PAUSE");

return 0;

}

原文:http://bbs.chinaunix.net/viewthread.php?tid=1493809
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: