南京师范大学数据结构考研真题.docx

上传人:b****8 文档编号:9393189 上传时间:2023-02-04 格式:DOCX 页数:16 大小:19.81KB
下载 相关 举报
南京师范大学数据结构考研真题.docx_第1页
第1页 / 共16页
南京师范大学数据结构考研真题.docx_第2页
第2页 / 共16页
南京师范大学数据结构考研真题.docx_第3页
第3页 / 共16页
南京师范大学数据结构考研真题.docx_第4页
第4页 / 共16页
南京师范大学数据结构考研真题.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

南京师范大学数据结构考研真题.docx

《南京师范大学数据结构考研真题.docx》由会员分享,可在线阅读,更多相关《南京师范大学数据结构考研真题.docx(16页珍藏版)》请在冰豆网上搜索。

南京师范大学数据结构考研真题.docx

南京师范大学数据结构考研真题

(1)设计一个程序,找出1-200之间的所有水仙花数。

所谓水仙花数是指各个数字的立方和恰好等于该数本身。

例如:

153=1*1*1+5*5*5+3*3*3。

(本题15分)

#include

voidmain()

{

inti,j,k,n;

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

{

i=n/100;

j=(n-i*100)/10;

k=n%100%10;

if(i*i*i+j*j*j+k*k*k==n)

printf("%3disanarcissusnumber.\n",n);

}

}

#include

voidmain()

{

inti,j,s,n;

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

{

j=n;

i=0;

s=0;

while(j!

=0)

{

i=j%10;

s+=i*i*i;

j=j/10;

}

if(s==n)

printf("%3disanarcissusnumber.\n",n);

}

}

(2)设计一个程序,实现输入一个给定的正整数N,打印出所有不超过N的,其平方为回文(回文是指字符串两半的字符左右对称,例如1,22,121,4224等均是回文)的数(本题15分)

#includevoidtest(intn)

{

inti=0,j=-1,k;

inta[10];

k=n*n;

while(k!

=0)

{

a[++j]=k%10;

k=k/10;

}

while(i

{

if(a[i]==a[j])

{

i++;

j--;

}

else

break;

}

if(i>=j)

printf("%d'ssquare%disapalindromenumber!

\n",n,n*n);

}

voidmain()

{

inti,n;

printf("pleaseinputanumber:

");

scanf("%d",&n);

for(i=1;i

test(i);

}

(3)编写程序用于统计字符串中最长单词的长度和在字符串中的位置,其中单词由字母组成。

(本题20分)

#include

Voidmain()

{

inti,count=0,pos=0,maxlen=0;

charch;

chars[80]="whatareyoudoing";

//printf("inputastring:

");

//gets(s);

i=-1;

do{

i++;

ch=s[i];

if((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z'))

{

count++;

}

else{

if(count>maxlen)

{

maxlen=count;

pos=i-maxlen;

}

count=0;

}

}while(s[i]!

='\0');

printf("Themaxlengthwordis\"");

for(i=0;i

{

printf("%c",s[pos+i]);

}

printf("\"andit'spositionis%d.\n",pos+1);

}

(4)编写算法输出从n个自然数中取k个(k<=n)所有组合。

例如,当n=5,k=3时,你的算法应该输出:

543,542,541,532,531,521,432,431,421,321.(本题20分)

#include

Voidf(intn,intk,inta[],intm)

{

inti;

if(k==0)

{

for(i=0;i

printf("%d",a[i]);

printf("");

}

else{

for(i=n;i>=k;i--)

{

a[m]=i;

f(i-1,k-1,a,m+1);

}

}

}

voidmain()

{

intn,k,m=0;

inta[10];

printf("Pleaseenternandk:

");

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

f(n,k,a,m);

printf("\n");

}

(5)试采用递归函数实现将任意位数的整数转换成字符串输出,要求在主函数中输入整数并调用递归函数实现转换并输出结果,对于负数也能处理。

(本题20分)

#includevoidnumtostring(intn,chara[],intk)

{

if(k==0)return;

else{

a[--k]=n%10+48;

n/=10;

numtostring(n,a,k);

}

}

voidmain()

{

intn,m,k=0;

chara[100],sign='';

printf("Pleaseinputthenumber:

");

scanf("%d",&n);

if(n<0){sign='-';n=-n;}

m=n;

while(m)

{

k++;

m/=10;

}

a[k]='\0';

numtostring(n,a,k);

printf("Thenumberis:

%c%s\n",sign,a);

}

(6)假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A和表B归并成一个按元素非递减有序(允许值相同)排列的线性表C,并要求利用原表(即表A和表B)的结点空间存储放表。

(本题20分)

typedefstructNode

{

ElemTypedata;

structNode*next;

}LNode;

LNode*merge(LNode*A,LNode*B)

{

LNode*C;

LNode*pa,*pb,*pc;

pa=A->next;pb=B->next;

C=A;pc=C;pc->next=NULL;

while(pa&&pb)

{

if(pa->data<=pb->data)

{

pc->next=pa;

pa=pa->next;

pc=pc->next;

pc->next=NULL;

}

else{

pc->next=pb;

pb=pb->next;

pc=pc->next;

pc->next=NULL;

}

}

if(pa)pc->next=pa;

if(pb)pc->next=pb;

returnC;

}

(7)如果一棵Huffman树T有n个叶子结点,那么树T有多少个结点,要求给出详细的算法,然后再写出程序。

(本题20分)

参考解答:

解题思路:

假设有10个节点分别为9,7,5,3,1,8,6,4,2,0

将这些节点按从小到大的顺序存入链表中即0,1,2,3,4,5,6,7,8,9

取出前两个最小的节点,组成一个新的节点再放入到链表中,如下:

1,1,2,3,4,5,6,7,8,9

01

再对剩余的节点进行类似操作,直到剩余一个节点。

形成Huffman树后,然后统计节点的个数。

<1>voidInsertNode(LinkListh,LNode*s)是将*s指向的节点插入到以h为头节点的链表中适当位置,保证从小到大的排列顺序。

<2>voidFormLinkList(LinkList&h,inta[],intn)将数组a[n]中的n个元素放入到以h为头节点的链表中,保证链表从小到大

有序排列;将调用InsertNode(LinkListh,LNode*s)函数。

<3>BiTreeFormHuffman(LinkListh)是根据觛思路将带头节点的链表h逐步构建Huffman树,并将Huffman树返回。

<4>intcount(BiTreeroot)是对Huffman树root的节点进行计数。

<5>voidInOrder(BiTreeroot)和voidprintLinkList(LinkListh)是辅助函数,分别对树进行中序遍历和对链表进行打印。

#include

#include

#defineN10typedefstructBiNode

{

intdata;

structBiNode*lchild,*rchild;

structBiNode*next;

}LNode,*LinkList,BiNode,*BiTree;

voidInsertNode(LinkListh,LNode*s)

{

LNode*p,*q;

p=h;

q=p->next;

while(q&&q->data<=s->data)

{

p=q;

q=p->next;

}

p->next=s;

s->next=q;

(h->data)++;

}

voidFormLinkList(LinkList&h,inta[],intn)

{

inti;

LNode*s;

if(!

(h=(LNode*)malloc(sizeof(LNode))))exit(0);

h->data=0;

h->next=NULL;

h->lchild=NULL;

h->rchild=NULL;

for(i=0;i

{

if(!

(s=(LNode*)malloc(sizeof(LNode))))exit(0);

s->data=a[i];

s->next=NULL;

s->lchild=NULL;

s->rchild=NULL;

InsertNode(h,s);

}

}

BiTreeFormHuffman(LinkListh)

{

LNode*p,*q;

BiNode*b;

if(h==NULL||h->data==0)returnNULL;

else{

while(h->data>1)

{

p=h->next;

q=p->next;

h->next=q->next;

(h->data)=h->data-2;

if(!

(b=(BiNode*)malloc(sizeof(BiNode))))exit(0);

b->data=p->data+q->data;

b->next=NULL;

b->lchild=p;

b->rchild=q;

InsertNode(h,b);

}

return(h->next);

}

}

intcount(BiTreeroot)

{

if(root==NULL)return0;

elseif(root->lchild==NULL&&root->rchild==NULL)return1;

else

return(

count(root->lchild)+

count(root->rchild)+1);

}

voidInOrder(BiTreeroot)

{

if(root)

{

InOrder(root->lchild);

printf("%d",root->data);

InOrder(root->rchild);

}

}

voidprintLinkList(LinkListh)

{

h=h->next;

while(h)

{

printf("%d",h->data);

h=h->next;

}

printf("\n");

}

voidmain()

{

inti;

inta[N]={9,7,5,3,1,8,6,4,2,0};

LinkListh;

BiTreeroot;

FormLinkList(h,a,N);

printLinkList(h);

root=FormHuffman(h);

InOrder(root);

i=count(root);

printf("\nTotalNumberofBiNodesis%d.\n",i);

}

(8)对于二叉树T的两个结点N1和N2,我们应该选择树T结点的前序、中序和后序中哪两个序列来判定结点N1必定是结点N2的祖先,并给出判断的方法。

要求给出详细的算法,然后再写出程序。

(本题20分)

参考答案:

有前中后三种序列,我们该选择哪一种呢?

我们先来做一个假设:

N1是N2的祖先。

此时N2有两种情况,一是N2在N1的左子树中,二是N2在N1的右子树中。

情况N2在N1的左子树N2在N1的右子树结果

前序N1...N2N1...N2相同

中序N2...N1N1...N2不同

后序N2...N1N2...N1相同

在前序序列中N1稳定排列于N2的前面,则N1有可能是N2的祖先,但并不代表N1一定是N2的祖先。

在后序序列中N1稳定排列于N2的后面,则N1有可能是N2的祖先,但并不代表N1一定是N2的祖先。

在中序序列中N1可能在N2的前面,也可能在N2的后面,这一点对我们判断N1是否可能是N2的祖先没有多大帮助。

由于中序序列存在这种不稳定性,我们只好采取前序和后序。

假如说有一种情况如下:

前序:

...N1...N2...

后序:

...N2...N1...

这两个序列,能判定N1是N2的祖先吗?

思考两个问题:

<1>N1是N2的祖先,则N1和N2的相对位置关系是上面的两个序列表现的这种前后关系吗?

<2>两个数列中N1和N2有这种前后关系,那N1一定是N2的祖先吗?

第1个问题,N1是N2的祖先,则N1和N2满足上述两个序列的前后关系。

第2个问题,不容易回答,因为当N1不是N2的祖先时,是否也能满足这种前后关系呢?

N1不是N2的祖先,分为两种情况:

一是N2是N1的祖先;二是N2是N1的兄弟树的结点,而第二种

情况又要分两种:

①N1是在左,N2在右;②N1在右,N2在左。

情况N1是N2的祖先N2是N1的祖先N1在左,N2在右N2在左,N1在右

前序N1...N2N2...N1N1...N2N2...N1

后序N2...N1N1...N2N1...N2N2...N1

后三组结果与第一组结果都不能完全相同,也就是说除了N1是N2祖先的情况,没有其它任何

情况可以产生上面的二个序列了,也就回答了第二个问题。

通过以上这些情况,可以看出前序和后序可以确定N1是否为N2的祖先。

#include

Intjudge(charpre[],charpost[],charch1,charch2)

{//pre[]代表前序序列,post[]代表后序序列,函数用检验ch1是否为ch2的祖先

Inti,k1=0,k2=0,flag=0;//k1、k2分别用来记录字符ch2在前序和后序中位置

while(pre[k1]!

=ch2)k1++;//flag用来标识进行判断ch1是否是ch2的祖先

while(post[k2]!

=ch2)k2++;

for(i=0;i

{

if(pre[i]==ch1)

{

flag=1;//如果ch1在ch2的前面找到,则先假设ch1是ch2的祖先

break;

}

}

if(!

flag)returnflag;//如果ch1不在ch2前面,则返回

else{

flag=0;//将flag重新赋值为0

for(i=k2+1;post[i]!

='\0';i++)//进一步进行判断

if(post[i]==ch1)

{

flag=1;

break;

}

Returnflag;

}

}

voidmain()

{

inti=0;

charch1,ch2,pre[100]={"abdecfg"},post[100]={"debfgca"};

printf("请输入前序序列:

");

//gets(pre);

puts(pre);

printf("请输入后序序列:

");

//gets(post);

puts(post);

printf("请输入要查询的字符N1和N2(形式:

N1,N2):

");

scanf("%c,%c",&ch1,&ch2);

i=judge(pre,post,ch1,ch2);

if(i)

printf("%c是%c的祖先\n",ch1,ch2);

elseprintf("%c不是%c的祖先\n",ch1,ch2);

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 文学研究

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1