南京师范大学数据结构考研真题Word文档格式.docx
- 文档编号:22529255
- 上传时间:2023-02-04
- 格式:DOCX
- 页数:16
- 大小:19.81KB
南京师范大学数据结构考研真题Word文档格式.docx
《南京师范大学数据结构考研真题Word文档格式.docx》由会员分享,可在线阅读,更多相关《南京师范大学数据结构考研真题Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。
inti=0,j=-1,k;
inta[10];
k=n*n;
while(k!
=0)
a[++j]=k%10;
k=k/10;
while(i<
j)
if(a[i]==a[j])
i++;
j--;
else
break;
if(i>
=j)
%d'
ssquare%disapalindromenumber!
\n"
n,n*n);
inti,n;
pleaseinputanumber:
"
);
scanf("
%d"
&
n);
for(i=1;
i<
n;
i++)
test(i);
(3)编写程序用于统计字符串中最长单词的长度和在字符串中的位置,其中单词由字母组成。
(本题20分)
Voidmain()
inti,count=0,pos=0,maxlen=0;
charch;
chars[80]="
whatareyoudoing"
;
//printf("
inputastring:
//gets(s);
i=-1;
do{
ch=s[i];
if((ch>
='
A'
&
&
ch<
Z'
)||(ch>
a'
z'
))
count++;
else{
if(count>
maxlen)
maxlen=count;
pos=i-maxlen;
count=0;
}while(s[i]!
\0'
Themaxlengthwordis\"
for(i=0;
maxlen;
%c"
s[pos+i]);
\"
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分)
Voidf(intn,intk,inta[],intm)
inti;
if(k==0)
m;
a[i]);
"
for(i=n;
i>
=k;
i--)
a[m]=i;
f(i-1,k-1,a,m+1);
intn,k,m=0;
Pleaseenternandk:
%d%d"
n,&
k);
f(n,k,a,m);
(5)试采用递归函数实现将任意位数的整数转换成字符串输出,要求在主函数中输入整数并调用递归函数实现转换并输出结果,对于负数也能处理。
voidnumtostring(intn,chara[],intk)
if(k==0)return;
a[--k]=n%10+48;
n/=10;
numtostring(n,a,k);
intn,m,k=0;
chara[100],sign='
'
Pleaseinputthenumber:
if(n<
0){sign='
-'
n=-n;
m=n;
while(m)
k++;
m/=10;
a[k]='
Thenumberis:
%c%s\n"
sign,a);
(6)假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A和表B归并成一个按元素非递减有序(允许值相同)排列的线性表C,并要求利用原表(即表A和表B)的结点空间存储放表。
typedefstructNode
ElemTypedata;
structNode*next;
}LNode;
LNode*merge(LNode*A,LNode*B)
LNode*C;
LNode*pa,*pb,*pc;
pa=A->
next;
pb=B->
C=A;
pc=C;
pc->
next=NULL;
while(pa&
pb)
if(pa->
data<
=pb->
data)
next=pa;
pa=pa->
pc=pc->
next=pb;
pb=pb->
if(pa)pc->
if(pb)pc->
returnC;
(7)如果一棵Huffman树T有n个叶子结点,那么树T有多少个结点,要求给出详细的算法,然后再写出程序。
参考解答:
解题思路:
假设有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)是辅助函数,分别对树进行中序遍历和对链表进行打印。
stdlib.h>
#defineN10typedefstructBiNode
intdata;
structBiNode*lchild,*rchild;
structBiNode*next;
}LNode,*LinkList,BiNode,*BiTree;
voidInsertNode(LinkListh,LNode*s)
LNode*p,*q;
p=h;
q=p->
while(q&
q->
data<
=s->
p=q;
p->
next=s;
s->
next=q;
(h->
data)++;
voidFormLinkList(LinkList&
h,inta[],intn)
LNode*s;
if(!
(h=(LNode*)malloc(sizeof(LNode))))exit(0);
h->
data=0;
lchild=NULL;
rchild=NULL;
(s=(LNode*)malloc(sizeof(LNode))))exit(0);
data=a[i];
InsertNode(h,s);
BiTreeFormHuffman(LinkListh)
BiNode*b;
if(h==NULL||h->
data==0)returnNULL;
while(h->
data>
1)
p=h->
next=q->
data)=h->
data-2;
(b=(BiNode*)malloc(sizeof(BiNode))))exit(0);
b->
data=p->
data+q->
data;
lchild=p;
rchild=q;
InsertNode(h,b);
return(h->
next);
intcount(BiTreeroot)
if(root==NULL)return0;
elseif(root->
lchild==NULL&
root->
rchild==NULL)return1;
return(
count(root->
lchild)+
rchild)+1);
voidInOrder(BiTreeroot)
if(root)
InOrder(root->
lchild);
%d"
root->
data);
rchild);
voidprintLinkList(LinkListh)
h=h->
while(h)
h->
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);
\nTotalNumberofBiNodesis%d.\n"
i);
(8)对于二叉树T的两个结点N1和N2,我们应该选择树T结点的前序、中序和后序中哪两个序列来判定结点N1必定是结点N2的祖先,并给出判断的方法。
要求给出详细的算法,然后再写出程序。
参考答案:
有前中后三种序列,我们该选择哪一种呢?
我们先来做一个假设:
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的祖先吗?
思考两个问题:
N1是N2的祖先,则N1和N2的相对位置关系是上面的两个序列表现的这种前后关系吗?
两个数列中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的祖先。
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++;
k1;
if(pre[i]==ch1)
flag=1;
//如果ch1在ch2的前面找到,则先假设ch1是ch2的祖先
flag)returnflag;
//如果ch1不在ch2前面,则返回
flag=0;
//将flag重新赋值为0
for(i=k2+1;
post[i]!
i++)//进一步进行判断
if(post[i]==ch1)
Returnflag;
inti=0;
charch1,ch2,pre[100]={"
abdecfg"
},post[100]={"
debfgca"
};
请输入前序序列:
//gets(pre);
puts(pre);
请输入后序序列:
//gets(post);
puts(post);
请输入要查询的字符N1和N2(形式:
N1,N2):
%c,%c"
ch1,&
ch2);
i=judge(pre,post,ch1,ch2);
if(i)
%c是%c的祖先\n"
ch1,ch2);
elseprintf("
%c不是%c的祖先\n"
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 南京师范大学 数据结构 考研