2022年下半年河北省C++语言版高级_第1页
2022年下半年河北省C++语言版高级_第2页
2022年下半年河北省C++语言版高级_第3页
2022年下半年河北省C++语言版高级_第4页
2022年下半年河北省C++语言版高级_第5页
已阅读5页,还剩71页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第第页2022年下半年河北省C++语言版高级2022年下半年河北省C++语言版高级

1、冒泡排序算法是把大的元素向上移〔气泡的上浮〕,也可以把小的元素向下移〔气泡的下沉〕请给出上浮和下沉过程交替的冒泡排序算法。

48.有n个记录存储在带头结点的双向链表中,现用双向起泡排序法对其按上升序进行排序,请写出这种排序的算法。〔注:双向起泡排序即相邻两趟排序向相反方向起泡〕

2、已知有向图G=(V,E),其中V={V1,V2,V3,V4,V5,V6,V7},E={V1,V2,V1,V3,V1,V4,V2,V5,V3,V5,V3,V6,V4,V6,V5,V7,V6,V7}

写出G的拓扑排序的结果。

G拓扑排序的结果是:V1、V2、V4、V3、V5、V6、V7

3、设有一个数组中存放了一个无序的关键序列K1、K2、…、Kn。现要求将Kn放在将元素排序后的正确位置上,试编写实现该功能的算法,要求比较关键字的次数不超过n。

51.借助于快速排序的算法思想,在一组无序的记录中查找给定关键字值等于key的记录。设此组记录存放于数组r[l..h]中。假设查找胜利,那么输出该记录在r数组中的位置及其值,否那么显示“notfind”信息。请编写出算法并简要说明算法思想。

4、后序遍历最末访问根结点,即在递归算法中,根是压在栈底的。采纳后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中全部元素均为该结点的祖先。此题要找p和q的最近共同祖先结点r,不失一般性,设p在q的左边。后序遍历必定先遍历到结点p,栈中元素均为p的祖先。将栈拷入另一帮助栈中。再继续遍历到结点q时,将栈中元素从栈顶开始逐个到帮助栈中去匹配,第一个匹配〔即相等〕的元素就是结点p和q的最近公共祖先。

typedefstruct

{BiTreet;inttag;//tag=0表示结点的左子女已被访问,tag=1表示结点的右子女已被访问

}stack;

stacks[],s1[];//栈,容量够大

BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。

{top=0;bt=ROOT;

while(bt!=null||top0)

{while(bt!=nullbt!=pbt!=q)//结点入栈

{s[++top].t=bt;s[top].tag=0;bt=bt-lchild;}//沿左分枝向下

if(bt==p)//不失一般性,假定p在q的左侧,遇结点p时,栈中元素均为p的祖先结点

{for(i=1;i=top;i++)s1[i]=s[i];top1=top;}//将栈s的元素转入帮助栈s1保存

if(bt==q)//找到q结点。

for(i=top;i0;i--)//;将栈中元素的树结点到s1去匹配

{pp=s[i].t;

for(j=top1;j0;j--)

if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}

while(top!=0s[top].tag==1)top--;//退栈

if(top!=0){s[top].tag=1;bt=s[top].t-rchild;}//沿右分枝向下遍历

}//结束whil

e(bt!=null||top0)

return(null);//q、p无公共祖先

}//结束Ancestor

5、#definema*size栈空间容量

voidInOutS(int

2022年下半年河北省C++语言版高级

s[ma*size])

//s是元素为整数的栈,本算法进行入栈和退栈操作。

{inttop=0;//top为栈顶指针,定义top=0时为栈空。

for(i=1;i=n;i++)//n个整数序列作处理。

{scanf(“%d”,*);//从键盘读入整数序列。

if(*!=-1)//读入的整数不等于-1时入栈。

if(top==ma*size-1){printf(“栈满\n”);e*it(0);}

elses[++top]=*;//*入栈。

else//读入的整数等于-1时退栈。

{if(top==0){printf(“栈空\n”);e*it(0);}

elseprintf(“出栈元素是%d\n”,s[top--]);}

}

}//算法结

6、给定n个村庄之间的交通图,假设村庄i和j之间有道路,那么将顶点i和j用边连接,边上的Wij表示这条道路的长度,现在要从这n个村庄中选择一个村庄建一所医院,问这所医院应建在哪个村庄,才能使离医院最远的村庄到医院的路程最短?试设计一个解答上述问题的算法,并应用该算法解答如下图的实例。20分

voidHospital(AdjMatri*w,intn)

//在以邻接带权矩阵表示的n个村庄中,求医院建在何处,使离医院最远的村庄到医院的路径最短。

{for(k=1;k=n;k++)//求任意两顶点间的最短路径

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

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

if(w[i][k]+w[k][j]w[i][j])w[i][j]=w[i][k]+w[k][j];

m=MA*INT;//设定m为机器内最大整数。

for(i=1;i=n;i++)//求最长路径中最短的一条。

{s=0;

for(j=1;j=n;j++)//求从某村庄i〔1=i=n〕到其它村庄的最长路径。

if(w[i][j]s)s=w[i][j];

if(s=m){m=s;k=i;}//在最长路径中,取最短的一条。m记最长路径,k记出发顶点的下标。

Printf(“医院应建在%d村庄,到医院距离为%d\n”,i,m);

}//for

}//算法结束

对以上实例模拟的过程略。各行中最大数依次是9,9,6,7,9,9。这几个最大数中最小者为6,故医院应建在第三个村庄中,离医院最远的村庄到医院的距离是6。

1、对图1所示的连通网G,请用Prim算法构造其最小生成树〔每选取一条边画一个图〕。

7、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,假设不再连通,那么将该边复原。假设仍连通,继续向下删;直到剩n-1条边为止。

voidSpnTree(AdjListg)

//用“破圈法”求解带

权连通无向图的一棵最小代价生成树。

{typedefstruct{inti,j,w}node;//设顶点信息就是顶点编号,权是整型数

nodeedge[];

scanf(%d%d,e,n);//输入边数和顶点数。

for

2022年下半年河北省C++语言版高级

(i=1;i=e;i++)//输入e条边:顶点,权值。

scanf(%d%d%d,edge[i].i,edge[i].j,edge[i].w);

for(i=2;i=e;i++)//按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i];j=i-1;

while(edge[j].wedge[0].w)edge[j+1]=edge[j--];

edge[j+1]=edge[0];}//for

k=1;eg=e;

while(eg=n)//破圈,直到边数e=n-1.

{if(connect(k))//删除第k条边假设仍连通。

{edge[k].w=0;eg--;}//测试下一条边edge[k],权值置0表示该边被删除

k++;//下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

8、请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺次连成一个单链表,表头指针为head。二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。分析你的算法的时、空繁复度。

9、给出折半查找的递归算法,并给出算法时间繁复度性分析。

10、假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简约有向回路,假设存在,那么以顶点序列的方式输出该回路〔找到一条即可〕。〔注:图中不存在顶点到自己的弧〕

有向图判断回路要比无向图繁复。利用深度优先遍历,将顶点分成三类:未访问;已访问但其邻接点未访问完;已访问且其邻接点已访问完。下面用0,1,2表示这三种状态。前面已提到,假设dfs〔v〕结束前涌现顶点u到v的回边,那么图中必有包含顶点v和u的回路。对应程序中v的状态为1,而u是正访问的顶点,假设我们找出u的下一邻接点的状态为1,就可以输出回路了。

voidPrint(intv,intstart)//输出从顶点start开始的回路。

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

if(g[v][i]!=0visited[i]==1)//假设存在边〔v,i〕,且顶点i的状态为1。

{printf(“%d”,v);

if(i==start)printf(“\n”);elsePrint(i,start);break;}//if

}//Print

voiddfs(intv)

{visited[v]=1;

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

if(g[v][j]!=0)//存在边(v,j)

if(visited[j]!=1){if(!visited[j])dfs(j);}//if

else{cycle=1;Print(j,j);}

visited[v]=2;

}//dfs

voidfind_cycle()//判断是否有回路,有那么输出邻接矩阵。visited数组为全局变量。

{for(i=1;i=n;i++)visited[i]=0;

for(i=1;i=n;i++)if(!visited[i])dfs(i);

}//find_cycle

11、假设K1,…,Kn是n个关键词,试解答:

试用二叉查找树的插入算法建立

一棵二叉查找树,即当关键词的插入次序为K1,K2,…,Kn时,用算法建立一棵以LLINK/RLINK链接表示的二叉查找树。

12、有一个带头结点的单链表,每个结点包括两个域,一个是整型域info,另一个是指向下一个结点的指针域ne*t。假设单链表已建立,设计算法删除单链表中所

2022年下半年河北省C++语言版高级

有重复涌现的结点,使得info域相等的结点只保留一个。

#includestdio.h

typedefchardatatype;

typedefstructnode{

datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

/**/

/*删除单链表中重复的结点*/

/**/

linklistdeletelist(linklisthead)

{listnode*p,*s,*q;

p=head-ne*t;

while(p)

{s=p;

q=p-ne*t;

while(q)

if(q-data==p-data)

{s-ne*t=q-ne*t;free(q);

q=s-ne*t;}

else

{s=q;/*找与P结点值相同的结点*/

q=q-ne*t;

}

p=p-ne*t;

}

returnhead;

}

13、对二叉树的某层上的结点进行运算,采纳队列结构按层次遍历最相宜。

intLeafKlevel(BiTreebt,intk)//求二叉树bt的第k(k1)层上叶子结点个数

{if(bt==null||k1)return(0);

BiTreep=bt,Q[];//Q是队列,元素是二叉树结点指针,容量足够大

intfront=0,rear=1,leaf=0;//front和rear是队头和队尾指针,leaf是叶子结点数

intlast=1,level=1;Q[1]=p;//last是二叉树同层最右结点的指针,level是二叉树的层数

while(front=rear)

{p=Q[++front];

if(level==k!p-lchild!p-rchild)leaf++;//叶子结点

if(p-lchild)Q[++rear]=p-lchild;//左子女入队

if(p-rchild)Q[++rear]=p-rchild;//右子女入队

if(front==last){level++;//二叉树同层最右结点已处理,层数增1

last=rear;}//last移到指向下层最右一元素

if(levelk)return(leaf);//层数大于k后退出运行

}//while}//结束LeafKLevel

14、二路插入排序是将待排关键字序列r[1..n]中关键字分二路分别按序插入到帮助向量d[1..n]前半部和后半部〔注:向量d可视为循环表〕,其原那么为,先将r[l]赋给d[1],再从r[2]记录开始分二路插入。编写实现二路插入排序算法。

15、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。

typedefstructnode{intdata;structnode*ne*t;}lklist;

voidintersection(lklist*ha,lklist*hb,lklist*hc)

{

lklist*p,*q,*t;

for(p=ha,hc=0;p!=0;p=p-ne*t)

{for(q=hb;q!=0;q=q-ne*t)if(q-data==p-data)break;

if(q!=0){t=(lklist*)malloc(sizeof(lklist));t-data=p-data;t-ne*t=hc;hc=t;}

}

}

16、设T是一棵满二叉树,编写一个将T的先序遍历序列转换为后序遍历序列的递

归算法。

17、请编写一个判别给定二叉树是否为二叉排序树的算法,设二叉树用llink-rlink法存储。

18、题目中要求矩阵两行元素的平均值按递增顺次排序,由于每行元素个数相等,按平均值排列与按每行元素之和排列是一个意思。所以应先求出各行元素之和,放入一维数组中,然后选择一种排序方

2022年下半年河北省C++语言版高级

法,对该数组进行排序,留意在排序时假设有元素移动,那么与之相应的行中各元素也需要做相应变动。

voidTranslation〔float*matri*,intn〕

//本算法对nn的矩阵matri*,通过行变换,使其各行元素的平均值按递增排列。

{inti,j,k,l;

floatsum,min;//sum暂存各行元素之和

float*p,*pi,*pk;

for(i=0;in;i++)

{sum=0.0;pk=matri*+i*n;//pk指向矩阵各行第1个元素.

for(j=0;jn;j++){sum+=*(pk);pk++;}//求一行元素之和.

*(p+i)=sum;//将一行元素之和存入一维数组.

}//fori

for(i=0;in-1;i++)//用选择法对数组p进行排序

{min=*(p+i);k=i;//初始设第i行元素之和最小.

for(j=i+1;jn;j++)if(p[j]min){k=j;min=p[j];}//记新的最小值及行号.

if(i!=k)//假设最小行不是当前行,要进行交换(行元素及行元素之和)

{pk=matri*+n*k;//pk指向第k行第1个元素.

pi=matri*+n*i;//pi指向第i行第1个元素.

for(j=0;jn;j++)//交换两行中对应元素.

{sum=*(pk+j);*(pk+j)=*(pi+j);*(pi+j)=sum;}

sum=p[i];p[i]=p[k];p[k]=sum;//交换一维数组中元素之和.

}//if

}//fori

free(p);//释放p数组.

}//Translation

[算法分析]算法中运用选择法排序,比较次数较多,但数据交换(移动)较少.假设用其它排序方法,虽可减削比较次数,但数据移动会增多.算法时间繁复度为O(n2).

19、4、voidLinkList_reverse(LinklistL)

//链表的就地逆置;为简化算法,假设表长大于2

{

p=L-ne*t;q=p-ne*t;s=q-ne*t;p-ne*t=NULL;

while(s-ne*t)

{

q-ne*t=p;p=q;

q=s;s=s-ne*t;//把L的元素逐个插入新表表头

}

q-ne*t=p;s-ne*t=q;L-ne*t=s;

}//LinkList_reverse

20、给出折半查找的递归算法,并给出算法时间繁复度性分析。

21、由二叉树的前序遍历和中序遍历序列能确定唯一的一棵二叉树,下面程序的作用是实现由已知某二叉树的前序遍历和中序遍历序列,生成一棵用二叉链表表示的二叉树并打印出后序遍历序列,请写出程序所缺的语句。

#defineMA*100

typedefstructNode

{charinfo;structNode*llink,*rlink;}TNODE;

charpred[MA*],inod[MA*];

main(intargc,int**argv)

{TNODE*root;

if(argc3)e*it0;

strcpy(pred,argv[1]);strcpy(inod,argv[2]);

root=restore(pred,inod,strlen(pred));

postorder(root);

}

TNODE*restore(char*ppos,char*ipos,intn)

{TNODE*ptr;char*rpos;intk;

if(n=0)returnNULL;

ptr-info=(1)_______;

for((2)_______;rposipos+n;rpos++)if(*rpos==*ppos)break;

k=(3)_______;

ptr-llink=restore(ppos+1,(4)_______,k);

ptr-rlink=restore((5)_______+k,rpos+1,n-1-k);

returnptr;

}

postorder(TNODE*p

tr)

{if(ptr=NULL)return;

postorder(ptr-llink);postorder(ptr-rlink);printf(“%c”,ptr-info);

}

22、后序遍历最末访问根结点,即在递归算法中,根是压在

2022年下半年河北省C++语言版高级

栈底的。采纳后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中全部元素均为该结点的祖先。此题要找p和q的最近共同祖先结点r,不失一般性,设p在q的左边。后序遍历必定先遍历到结点p,栈中元素均为p的祖先。将栈拷入另一帮助栈中。再继续遍历到结点q时,将栈中元素从栈顶开始逐个到帮助栈中去匹配,第一个匹配〔即相等〕的元素就是结点p和q的最近公共祖先。

typedefstruct

{BiTreet;inttag;//tag=0表示结点的左子女已被访问,tag=1表示结点的右子女已被访问

}stack;

stacks[],s1[];//栈,容量够大

BiTreeAncestor(BiTreeROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。

{top=0;bt=ROOT;

while(bt!=null||top0)

{while(bt!=nullbt!=pbt!=q)//结点入栈

{s[++top].t=bt;s[top].tag=0;bt=bt-lchild;}//沿左分枝向下

if(bt==p)//不失一般性,假定p在q的左侧,遇结点p时,栈中元素均为p的祖先结点

{for(i=1;i=top;i++)s1[i]=s[i];top1=top;}//将栈s的元素转入帮助栈s1保存

if(bt==q)//找到q结点。

for(i=top;i0;i--)//;将栈中元素的树结点到s1去匹配

{pp=s[i].t;

for(j=top1;j0;j--)

if(s1[j].t==pp){printf(“p和q的最近共同的祖先已找到”);return(pp);}

while(top!=0s[top].tag==1)top--;//退栈

if(top!=0){s[top].tag=1;bt=s[top].t-rchild;}//沿右分枝向下遍历

}//结束while(bt!=null||top0)

return(null);//q、p无公共祖先

}//结束Ancestor

23、对二叉树的某层上的结点进行运算,采纳队列结构按层次遍历最相宜。

intLeafKlevel(BiTreebt,intk)//求二叉树bt的第k(k1)层上叶子结点个数

{if(bt==null||k1)return(0);

BiTreep=bt,Q[];//Q是队列,元素是二叉树结点指针,容量足够大

intfront=0,rear=1,leaf=0;//front和rear是队头和队尾指针,leaf是叶子结点数

intlast=1,level=1;Q[1]=p;//last是二叉树同层最右结点的指针,level是二叉树的层数

while(front=rear)

{p=Q[++front];

if(level==k!p-lchild!p-rchild)leaf++;//叶子结点

if(p-lchild)Q[++rear]=p-lchild;//左子女入队

if(p-rchild)Q[++rear]=p-rchild;//右子女入队

if(front==last){level++;//二叉树同层最右结点已处理,层数增1

last=rear;}//last移到指向下层最右一元素

if(levelk)return(leaf);//层数大于k后退出运行

}//while}//结束LeafKLeve

l

24、请编写一个判别给定二叉树是否为二叉排序树的算法,设二叉树用llink-rlink法存储。

25、在有向图G中,假如r到G中的每个结点都有路径可达,那么称结点r为G的根结点。编写一个算法完成以下功能:

〔1〕.建立有向图G的邻接表存储结构;

〔2〕.判断有向图G是否有根

2022年下半年河北省C++语言版高级

,假设有,那么打印出全部根结点的值。

26、4、voidLinkList_reverse(LinklistL)

//链表的就地逆置;为简化算法,假设表长大于2

{

p=L-ne*t;q=p-ne*t;s=q-ne*t;p-ne*t=NULL;

while(s-ne*t)

{

q-ne*t=p;p=q;

q=s;s=s-ne*t;//把L的元素逐个插入新表表头

}

q-ne*t=p;s-ne*t=q;L-ne*t=s;

}//LinkList_reverse

27、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,假设不再连通,那么将该边复原。假设仍连通,继续向下删;直到剩n-1条边为止。

voidSpnTree(AdjListg)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。

{typedefstruct{inti,j,w}node;//设顶点信息就是顶点编号,权是整型数

nodeedge[];

scanf(%d%d,e,n);//输入边数和顶点数。

for(i=1;i=e;i++)//输入e条边:顶点,权值。

scanf(%d%d%d,edge[i].i,edge[i].j,edge[i].w);

for(i=2;i=e;i++)//按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i];j=i-1;

while(edge[j].wedge[0].w)edge[j+1]=edge[j--];

edge[j+1]=edge[0];}//for

k=1;eg=e;

while(eg=n)//破圈,直到边数e=n-1.

{if(connect(k))//删除第k条边假设仍连通。

{edge[k].w=0;eg--;}//测试下一条边edge[k],权值置0表示该边被删除

k++;//下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

28、约瑟夫环问题〔Josephus问题〕是指编号为1、2、…,n的n〔n0〕个人按顺时针方向围坐成一圈,现从第s个人开始按顺时针方向报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,…,如此重复直到全部的人全部出列为止。现要求采纳循环链表结构设计一个算法,模拟此过程。

#includestdlib.h

typedefintdatatype;

typedefstructnode

{datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

voidjose(linklisthead,ints,intm)

{linklistk1,pre,p;

intcount=1;

pre=NULL;

k1=head;/*k1为报数的起点*/

while(count!=s)/*找初始报数起点*/

{pre=k1;

k1=k1-ne*t;

count++;

}

while(k1-ne*t!=k1)/*当循环链表中的结点个数大于1时*/

{p=k1;/*从k1开始报数*/

count=1;

while(count!=m)/*连续数m个结点*/

{pre=p;

p=p-ne*t;

count++;

}

pre-ne*t=p-ne*t;

/*输出该结点,并删除该结点*/

printf(%4d,p-data);

free(p);

k1=pre-ne*t;/*新的报数起点*/

}

printf(%4d,k1-data);/*输出

2022年下半年河北省C++语言版高级

最末一个结点*/

free(k1);

}

main()

{linklisthead,p,r;

intn,s,m,i;

printf(n=);

scanf(%d,n);

printf(s=);

scanf(%d,s);

printf(m=,m);

scanf(%d,m);

if(n1)printf(n0);

else

{/*建表*/

head=(linklist)malloc(sizeof(listnode));/*建第一个结点*/

head-data=n;

r=head;

for(i=n-1;i0;i--)/*建立剩余n-1个结点*/

{p=(linklist)malloc(sizeof(listnode));

p-data=i;

p-ne*t=head;

head=p;

}

r-ne*t=head;/*生成循环链表*/

jose(head,s,m);/*调用函数*/

}

}

29、矩阵中元素按行和按列都已排序,要求查找时间繁复度为O〔m+n〕,因此不能采纳常规的二层循环的查找。可以先从右上角〔i=a,j=d〕元素与*比较,只有三种状况:一是A[i,j]*,这状况下向j小的方向继续查找;二是A[i,j]*,下步应向i大的方向查找;三是A[i,j]=*,查找胜利。否那么,假设下标已超出范围,那么查找失败。

voidsearch(datatypeA[][],inta,b,c,d,datatype*)

//n*m矩阵A,行下标从a到b,列下标从c到d,本算法查找*是否在矩阵A中.

{i=a;j=d;flag=0;//flag是胜利查到*的标识

while(i=bj=c)

if(A[i][j]==*){flag=1;break;}

elseif(A[i][j]*)j--;elsei++;

if(flag)printf(“A[%d][%d]=%d”,i,j,*);//假定*为整型.

elseprintf(“矩阵A中无%d元素”,*);

}算法search结束。

[算法争论]算法中查找*的路径从右上角开始,向下〔当*A[i,j]〕或向左〔当*A[i,j]〕。向下最多是m,向左最多是n。最正确状况是在右上角比较一次胜利,最差是在左下角〔A[b,c]〕,比较m+n次,故算法最差时间繁复度是O(m+n〕。

30、此题要求建立有序的循环链表。从头到尾扫描数组A,取出A[i]〔0=in〕,然后到链表中去查找值为A[i]的结点,假设查找失败,那么插入。

LinkedListcreat(ElemTypeA[],intn)

//由含n个数据的数组A生成循环链表,要求链表有序并且无值重复结点

{LinkedListh;

h=(LinkedList)malloc(sizeof(LNode));//申请结点

h-ne*t=h;//形成空循环链表

for(i=0;in;i++)

{pre=h;

p=h-ne*t;

while(p!=hp-dataA[i])

{pre=p;p=p-ne*t;}//查找A[i]的插入位置

if(p==h||p-data!=A[i])//重复数据不再输入

{s=(LinkedList)malloc(sizeof(LNode));

s-data=A[i];pre-ne*t=s;s-ne*t=p;//将结点s链入链表中

}

}//for

return(h);

}算法结束

31、有一个带头结点的单链表,每个结点包括两个域,一个是整型域info,另一个是指向下一个结点的指针域ne*t。假设单链表已建立,设计算法删除单链表中全部重复涌现的结点,使得info域相等的结点只保留一个。

#includestdio.h

typed

efchardatatype;

typedefstructnode{

datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

/*

2022年下半年河北省C++语言版高级

*/

/*删除单链表中重复的结点*/

/**/

linklistdeletelist(linklisthead)

{listnode*p,*s,*q;

p=head-ne*t;

while(p)

{s=p;

q=p-ne*t;

while(q)

if(q-data==p-data)

{s-ne*t=q-ne*t;free(q);

q=s-ne*t;}

else

{s=q;/*找与P结点值相同的结点*/

q=q-ne*t;

}

p=p-ne*t;

}

returnhead;

}

32、有一个带头结点的单链表,每个结点包括两个域,一个是整型域info,另一个是指向下一个结点的指针域ne*t。假设单链表已建立,设计算法删除单链表中全部重复涌现的结点,使得info域相等的结点只保留一个。

#includestdio.h

typedefchardatatype;

typedefstructnode{

datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

/**/

/*删除单链表中重复的结点*/

/**/

linklistdeletelist(linklisthead)

{listnode*p,*s,*q;

p=head-ne*t;

while(p)

{s=p;

q=p-ne*t;

while(q)

if(q-data==p-data)

{s-ne*t=q-ne*t;free(q);

q=s-ne*t;}

else

{s=q;/*找与P结点值相同的结点*/

q=q-ne*t;

}

p=p-ne*t;

}

returnhead;

}

33、依据二叉排序树中序遍历所得结点值为增序的性质,在遍历中将当前遍历结点与其前驱结点值比较,即可得出结论,为此设全局指针变量pre〔初值为null〕和全局变量flag,初值为true。假设非二叉排序树,那么置flag为false。

#definetrue1

#definefalse0

typedefstructnode

{datatypedata;structnode*llink,*rlink;}*BTree;

voidJudgeBST〔BTreet,intflag〕

//判断二叉树是否是二叉排序树,本算法结束后,在调用程序中由flag得出结论。

{if〔t!=nullflag〕

{Judgebst〔t-llink,flag〕;//中序遍历左子树

if〔pre==null〕pre=t;//中序遍历的第一个结点不必判断

elseif〔pre-datat-data〕pre=t;//前驱指针指向当前结点

else{flag=flase;}//不是完全二叉树

Judgebst〔t-rlink,flag〕;//中序遍历右子树

}//JudgeBST算法结束

34、设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C,G)},要求用孩子兄弟表示法〔二叉链表〕表示出该树的存储结构并将该树转化

成对应的二叉树。

35、二叉树的层次遍历序列的第一个结点是二叉树的根。事实上,层次遍历序列中的每个结点都是“局部根”。确定根后,到二叉树的中序序列中,查到该结点,该结点将二叉树分为“左根右”三部分。假设左、右子树均有,那么层次序列根结点的后面应是左右子树的根;假设中序序列中只有左子树或只有

2022年下半年河北省C++语言版高级

右子树,那么在层次序列的根结点后也只有左子树的根或右子树的根。这样,定义一个全局变量指针R,指向层次序列待处理元素。算法中先处理根结点,将根结点和左右子女的信息入队列。然后,在队列不空的条件下,循环处理二叉树的结点。队列中元素的数据结构定义如下:

typedefstruct

{intlvl;//层次序列指针,总是指向当前“根结点”在层次序列中的位置

intl,h;//中序序列的下上界

intf;//层次序列中当前“根结点”的双亲结点的指针

intlr;//1—双亲的左子树2—双亲的右子树

}qnode;

BiTreeCreat(datatypein[],level[],intn)

//由二叉树的层次序列level[n]和中序序列in[n]生成二叉树。n是二叉树的结点数

{if(n1){printf(“参数错误\n”);e*it(0);}

qnodes,Q[];//Q是元素为qnode类型的队列,容量足够大

init(Q);intR=0;//R是层次序列指针,指向当前待处理的结点

BiTreep=(BiTree)malloc(sizeof(BiNode));//生成根结点

p-data=level[0];p-lchild=null;p-rchild=null;//填写该结点数据

for(i=0;in;i++)//在中序序列中查找根结点,然后,左右子女信息入队列

if(in[i]==level[0])break;

if(i==0)//根结点无左子树,遍历序列的1—n-1是右子树

{p-lchild=null;

s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);

}

elseif(i==n-1)//根结点无右子树,遍历序列的1—n-1是左子树

{p-rchild=null;

s.lvl=++R;s.l=1;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);

}

else//根结点有左子树和右子树

{s.lvl=++R;s.l=0;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子树有关信息入队列

s.lvl=++R;s.l=i+1;s.h=n-1;s.f=p;s.lr=2;enqueue(Q,s);//右子树有关信息入队列

}

while(!empty(Q))//当队列不空,进行循环,构造二叉树的左右子树

{s=delqueue(Q);father=s.f;

for(i=s.l;i=s.h;i++)

if(in[i]==level[s.lvl])break;

p=(bitreptr)malloc(sizeof(binode));//申请结点空间

p-data=level[s.lvl];p-lchild=null;p-rchild=null;//填写该结点数据

if(s.lr==1)father-lchild=p;

elsefather-rchild=p;//让双亲的子女指针指向该结点

if(i==s.l)

{p-lchild=null;//处理无左子女

s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqueue(Q,s);

}

elseif(i==s.h)

{p-rchild=null;//处理无右子女

s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);

}

else{s.lvl=++R;s.h=i-1;s.f=p;s.lr=1;enqueue(Q,s);//左子树有关信息入队列

s.lvl=++R;s.l=i+1;s.f=p;s.lr=2;enqu

eue(Q,s);//右子树有关信息入队列

}

}//结束while(!empty(Q))

return(p);

}//算法结束

36、矩阵中元素按行和按列都已排序,要求查找时间繁复度为O〔m+n〕,因此不能采纳常规的二层循环的查找。可以先从右上角〔i=a,j=d〕元素

2022年下半年河北省C++语言版高级

与*比较,只有三种状况:一是A[i,j]*,这状况下向j小的方向继续查找;二是A[i,j]*,下步应向i大的方向查找;三是A[i,j]=*,查找胜利。否那么,假设下标已超出范围,那么查找失败。

voidsearch(datatypeA[][],inta,b,c,d,datatype*)

//n*m矩阵A,行下标从a到b,列下标从c到d,本算法查找*是否在矩阵A中.

{i=a;j=d;flag=0;//flag是胜利查到*的标识

while(i=bj=c)

if(A[i][j]==*){flag=1;break;}

elseif(A[i][j]*)j--;elsei++;

if(flag)printf(“A[%d][%d]=%d”,i,j,*);//假定*为整型.

elseprintf(“矩阵A中无%d元素”,*);

}算法search结束。

[算法争论]算法中查找*的路径从右上角开始,向下〔当*A[i,j]〕或向左〔当*A[i,j]〕。向下最多是m,向左最多是n。最正确状况是在右上角比较一次胜利,最差是在左下角〔A[b,c]〕,比较m+n次,故算法最差时间繁复度是O(m+n〕。

37、假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否那么称为非法序列。〔15分〕

〔1〕A和D是合法序列,B和C是非法序列。

〔2〕设被判定的操作序列已存入一维数组A中。

intJudge(charA[])

//判断字符数组A中的输入输出序列是否是合法序列。如是,返回true,否那么返回false。

{i=0;//i为下标。

j=k=0;//j和k分别为I和字母O的的个数。

while(A[i]!=‘\0’)//当未到字符数组尾就作。

{switch(A[i])

{case‘I’:j++;break;//入栈次数增1。

case‘O’:k++;if(kj){printf(“序列非法\n”);e*it(0);}

}

i++;//不论A[i]是‘I’或‘O’,指针i均后移。}

if(j!=k){printf(“序列非法\n”);return(false);}

else{printf(“序列合法\n”);return(true);}

}//算法结束。

38、设指针变量p指向双向链表中结点A,指针变量q指向被插入结点B,要求给出在结点A的后面插入结点B的操作序列〔设双向链表中结点的两个指针域分别为llink和rlink〕。

39、设一棵二叉树的结点结构为(LLINK,INFO,RLINK),ROOT为指向该二叉树根结点的指针,p和q分别为指向该二叉树中任意两个结点的指针,试编写一算法ANCESTOR〔ROOT,p,q,r〕,该算法找到p和q的最近共同祖先结点r。

40、我们可用“破圈法”求解带权连通无向图的一棵最小代价生成树。所谓“破圈法”就是“任取一圈,去掉圈上权最大的边”,反复执行这一步骤,直到没有圈为止。请给出用“破圈法”求解给定的带权连通无向图的一棵最小代价生成树的具体算法,并用程序实现你所给出的算法。注:圈就是回路。

41、有一个带

2022年下半年河北省C++语言版高级

头结点的单链表,每个结点包括两个域,一个是整型域info,另一个是指向下一个结点的指针域ne*t。假设单链表已建立,设计算法删除单链表中全部重复涌现的结点,使得info域相等的结点只保留一个。

#includestdio.h

typedefchardatatype;

typedefstructnode{

datatypedata;

structnode*ne*t;

}listnode;

typedeflistnode*linklist;

/**/

/*删除单链表中重复的结点*/

/**/

linklistdeletelist(linklisthead)

{listnode*p,*s,*q;

p=head-ne*t;

while(p)

{s=p;

q=p-ne*t;

while(q)

if(q-data==p-data)

{s-ne*t=q-ne*t;free(q);

q=s-ne*t;}

else

{s=q;/*找与P结点值相同的结点*/

q=q-ne*t;

}

p=p-ne*t;

}

returnhead;

}

42、将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,那么为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。

intBPGraph(AdjMatri*g)

//判断以邻接矩阵表示的图g是否是二部图。

{ints[];//顶点向量,元素值表示其属于那个集合〔值1和2表示两个集合〕

intQ[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。

intf=0,r,visited[];//f和r分别是队列的头尾指针,visited[]是访问数组

for(i=1;i=n;i++){visited[i]=0;s[i]=0;}//初始化,各顶点未确定属于那个集合

Q[1]=1;r=1;s[1]=1;//顶点1放入集合S1

while(fr)

{v=Q[++f];if(s[v]==1)jh=2;elsejh=1;//预备v的邻接点的集合号

if(!visited[v])

{visited[v]=1;//确保对每一个顶点,都要检查与其邻接点不应在一个集合中

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

if(g[v][j]==1){if(!s[j]){s[j]=jh;Q[++r]=j;}//邻接点入队列

elseif(s[j]==s[v])return(0);}//非二部图

}//if(!visited[v])

}//while

return(1);}//是二部图

[算法争论]题目给的是连通无向图,假设非连通,那么算法要修改。

43、设一棵树T中边的集合为{(A,B),(A,C),(A,D),(B,E),(C,F),(C,G)},要求用孩子兄弟表示法〔二叉链表〕表示出该树的存储结构并将该树转化成对应的二叉树。

44、假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简约有向回路,假设

存在,那么以顶点序列的方式输出该回路〔找到一条即可〕。〔注:图中不存在顶点到自己的弧〕

有向图判断回路要比无向图繁复。利用深度优先遍历,将顶点分成三类:未访问;已访问但其邻接点未访问完;已访问且其邻接点已访问完。下面用0,1,2表示这三种状态。前面已提到,假设dfs〔v〕结束前涌现顶点u到

2022年下半年河北省C++语言版高级

v的回边,那么图中必有包含顶点v和u的回路。对应程序中v的状态为1,而u是正访问的顶点,假设我们找出u的下一邻接点的状态为1,就可以输出回路了。

voidPrint(intv,intstart)//输出从顶点start开始的回路。

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

if(g[v][i]!=0visited[i]==1)//假设存在边〔v,i〕,且顶点i的状态为1。

{printf(“%d”,v);

if(i==start)printf(“\n”);elsePrint(i,start);break;}//if

}//Print

voiddfs(intv)

{visited[v]=1;

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

if(g[v][j]!=0)//存在边(v,j)

if(visited[j]!=1){if(!visited[j])dfs(j);}//if

else{cycle=1;Print(j,j);}

visited[v]=2;

}//dfs

voidfind_cycle()//判断是否有回路,有那么输出邻接矩阵。visited数组为全局变量。

{for(i=1;i=n;i++)visited[i]=0;

for(i=1;i=n;i++)if(!visited[i])dfs(i);

}//find_cycle

45、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,假设不再连通,那么将该边复原。假设仍连通,继续向下删;直到剩n-1条边为止。

voidSpnTree(AdjListg)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。

{typedefstruct{inti,j,w}node;//设顶点信息就是顶点编号,权是整型数

nodeedge[];

scanf(%d%d,e,n);//输入边数和顶点数。

for(i=1;i=e;i++)//输入e条边:顶点,权值。

scanf(%d%d%d,edge[i].i,edge[i].j,edge[i].w);

for(i=2;i=e;i++)//按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i];j=i-1;

while(edge[j].wedge[0].w)edge[j+1]=edge[j--];

edge[j+1]=edge[0];}//for

k=1;eg=e;

while(eg=n)//破圈,直到边数e=n-1.

{if(connect(k))//删除第k条边假设仍连通。

{edge[k].w=0;eg--;}//测试下一条边edge[k],权值置0表示该边被删除

k++;//下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

46、已知有向图G=(V,E),其中V={V1,V2,V3,V4,V5,V6,V7},E={V1,V2,V1,V3,V1,V4,V2,V5,V3,V5,V3,V6,V4,V6,V5,V7,V6,V7}

写出G的拓扑排序的结果。

G拓扑排序的结果是:V1、V2、V4、V3、V5、V6、V7

47、设T是一棵满二叉树,编写一个将T的先序遍历序列转换为后序遍历序列的递归算法。

48

、依据二叉排序树中序遍历所得结点值为增序的性质,在遍历中将当前遍历结点与其前驱结点值比较,即可得出结论,为此设全局指针变量pre〔初值为null〕和全局变量flag,初值为true。假设非二叉排序树,那么置flag为false。

#definetrue1

#definefalse

2022年下半年河北省C++语言版高级

0

typedefstructnode

{datatypedata;structnode*llink,*rlink;}*BTree;

voidJudgeBST〔BTreet,intflag〕

//判断二叉树是否是二叉排序树,本算法结束后,在调用程序中由flag得出结论。

{if〔t!=nullflag〕

{Judgebst〔t-llink,flag〕;//中序遍历左子树

if〔pre==null〕pre=t;//中序遍历的第一个结点不必判断

elseif〔pre-datat-data〕pre=t;//前驱指针指向当前结点

else{flag=flase;}//不是完全二叉树

Judgebst〔t-rlink,flag〕;//中序遍历右子树

}//JudgeBST算法结束

49、设t是给定的一棵二叉树,下面的递归程序count(t)用于求得:二叉树t中具有非空的左,右两个儿子的结点个数N2;只有非空左儿子的个数NL;只有非空右儿子的结点个数NR和叶子结点个数N0。N2、NL、NR、N0都是全局量,且在调用count(t)之前都置为0.

typedefstructnode

{intdata;structnode*lchild,*rchild;}node;

intN2,NL,NR,N0;

voidcount(node*t)

{if(t-lchild!=NULL)if(1)___N2++;elseNL++;

elseif(2)___NR++;else(3)__;

if(t-lchild!=NULL)(4)____;if(t-rchild!=NULL)(5)____;

}

26.树的先序非递归算法。

voide*ample(b)

btree*b;

{btree*stack[20],*p;

inttop;

if(b!=null)

{top=1;stack[top]=b;

while(top0)

{p=stack[top];top--;

printf(“%d”,p-data);

if(p-rchild!=null)

{(1)___;(2)___;

}

if(p-lchild!=null)

(3)___;(4)__;

}}}}

50、设指针变量p指向双向链表中结点A,指针变量q指向被插入结点B,要求给出在结点A的后面插入结点B的操作序列〔设双向链表中结点的两个指针域分别为llink和rlink〕。

51、设有两个集合A和集合B,要求设计生成集合C=A∩B的算法,其中集合A、B和C用链式存储结构表示。

typedefstructnode{intdata;structnode*ne*t;}lklist;

voidintersection(lklist*ha,lklist*hb,lklist*hc)

{

lklist*p,*q,*t;

for(p=ha,hc=0;p!=0;p=p-ne*t)

{for(q=hb;q!=0;q=q-ne*t)if(q-data==p-data)break;

if(q!=0){t=(lklist*)malloc(sizeof(lklist));t-data=p-data;t-ne*t=hc;hc=t;}

}

}

52、两棵空二叉树或仅有根结点的二叉树相像;对非空二叉树,可判左右子树是否相像,采纳递归算法。

intSimilar(BiTreep,q)//判断二叉树p和q是否相像

{if(p==nullq==null)return(1);

elseif(!pq||p!q)return(0);

elsereturn(Similar(p-lchild,q-lchild)Similar(p-rchild,q-rchild))

}//结束Similar

53、数组A和B的元素分别有序,欲将两数组合并到C数组,使C仍有序,应将A和B拷贝到C,只要留意A和

B数组指针的运用,以及正确处理一数组读完数据后将另一数组余下元素复制到C中即可。

voidunion(intA[],B[],C[],m,n)

//整型数组A和B各有m和n个元素,前者递增有序,后者递减有序,本算法将A和B归并为递增有序的数组C。

{i=0;j=n-1;k=0

2022年下半年河北省C++语言版高级

;//i,j,k分别是数组A,B和C的下标,因用C描述,下标从0开始

while(imj=0)

if(a[i]b[j])c[k++]=a[i++]elsec[k++]=b[j--];

while(im)c[k++]=a[i++];

while(j=0)c[k++]=b[j--];

}算法结束

4、要求二叉树按二叉链表形式存储。15分

〔1〕写一个建立二叉树的算法。〔2〕写一个判别给定的二叉树是否是完全二叉树的算法。

BiTreeCreat()//建立二叉树的二叉链表形式的存储结构

{ElemType*;BiTreebt;

scanf(“%d”,*);//此题假定结点数据域为整型

if(*==0)bt=null;

elseif(*0)

{bt=(BiNode*)malloc(sizeof(BiNode));

bt-data=*;bt-lchild=creat();bt-rchild=creat();

}

elseerror(“输入错误”);

return(bt);

}//结束BiTree

intJudgeComplete(BiTreebt)//判断二叉树是否是完全二叉树,如是,返回1,否那么,返回0

{inttag=0;BiTreep=bt,Q[];//Q是队列,元素是二叉树结点指针,容量足够大

if(p==null)return(1);

QueueInit(Q);QueueIn(Q,p);//初始化队列,根结点指针入队

while(!QueueEmpty(Q))

{p=QueueOut(Q);//出队

if(p-lchild!tag)QueueIn(Q,p-lchild);//左子女入队

else{if(p-lchild)return0;//前边已有结点为空,本结点不空

elsetag=1;//首次涌现结点为空

if(p-rchild!tag)QueueIn(Q,p-rchild);//右子女入队

elseif(p-rchild)return0;elsetag=1;

}//while

return1;}//JudgeComplete

54、设t是给定的一棵二叉树,下面的递归程序count(t)用于求得:二叉树t中具有非空的左,右两个儿子的结点个数N2;只有非空左儿子的个数NL;只有非空右儿子的结点个数NR和叶子结点个数N0。N2、NL、NR、N0都是全局量,且在调用count(t)之前都置为0.

typedefstructnode

{intdata;structnode*lchild,*rchild;}node;

intN2,NL,NR,N0;

voidcount(node*t)

{if(t-lchild!=NULL)if(1)___N2++;elseNL++;

elseif(2)___NR++;else(3)__;

if(t-lchild!=NULL)(4)____;if(t-rchild!=NULL)(5)____;

}

26.树的先序非递归算法。

voide*ample(b)

btree*b;

{btree*stack[20],*p;

inttop;

if(b!=null)

{top=1;stack[top]=b;

while(top0)

{p=stack[top];top--;

printf(“%d”,p-data);

if(p-rchild!=null)

{(1)___;(2)___;

}

if(p-lchild!=null)

(3)___;(4)__;

}}}}

55、假设以邻接矩阵作为图的存储结构,编写算法判别在给定的有向图中是否存在一个简约有向回路,假设存在,那么以顶点序列的方式

输出该回路〔找到一条即可〕。〔注:图中不存在顶点到自己的弧〕

有向图判断回路要比无向图繁复。利用深度优先遍历,将顶点分成三类:未访问;已访问但其邻接点未访问完;已访问且其邻接点已访问完。下面用0,1,2表示这三种状态。前面已提到,假设dfs〔v〕结束前涌现顶点u到v的回边,那么图中必有包含

2022年下半年河北省C++语言版高级

顶点v和u的回路。对应程序中v的状态为1,而u是正访问的顶点,假设我们找出u的下一邻接点的状态为1,就可以输出回路了。

voidPrint(intv,intstart)//输出从顶点start开始的回路。

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

if(g[v][i]!=0visited[i]==1)//假设存在边〔v,i〕,且顶点i的状态为1。

{printf(“%d”,v);

if(i==start)printf(“\n”);elsePrint(i,start);break;}//if

}//Print

voiddfs(intv)

{visited[v]=1;

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

if(g[v][j]!=0)//存在边(v,j)

if(visited[j]!=1){if(!visited[j])dfs(j);}//if

else{cycle=1;Print(j,j);}

visited[v]=2;

}//dfs

voidfind_cycle()//判断是否有回路,有那么输出邻接矩阵。visited数组为全局变量。

{for(i=1;i=n;i++)visited[i]=0;

for(i=1;i=n;i++)if(!visited[i])dfs(i);

}//find_cycle

56、数组A和B的元素分别有序,欲将两数组合并到C数组,使C仍有序,应将A和B拷贝到C,只要留意A和B数组指针的运用,以及正确处理一数组读完数据后将另一数组余下元素复制到C中即可。

voidunion(intA[],B[],C[],m,n)

//整型数组A和B各有m和n个元素,前者递增有序,后者递减有序,本算法将A和B归并为递增有序的数组C。

{i=0;j=n-1;k=0;//i,j,k分别是数组A,B和C的下标,因用C描述,下标从0开始

while(imj=0)

if(a[i]b[j])c[k++]=a[i++]elsec[k++]=b[j--];

while(im)c[k++]=a[i++];

while(j=0)c[k++]=b[j--];

}算法结束

4、要求二叉树按二叉链表形式存储。15分

〔1〕写一个建立二叉树的算法。〔2〕写一个判别给定的二叉树是否是完全二叉树的算法。

BiTreeCreat()//建立二叉树的二叉链表形式的存储结构

{ElemType*;BiTreebt;

scanf(“%d”,*);//此题假定结点数据域为整型

if(*==0)bt=null;

elseif(*0)

{bt=(BiNode*)malloc(sizeof(BiNode));

bt-data=*;bt-lchild=creat();bt-rchild=creat();

}

elseerror(“输入错误”);

return(bt);

}//结束BiTree

intJudgeComplete(BiTreebt)//判断二叉树是否是完全二叉树,如是,返回1,否那么,返回0

{inttag=0;BiTreep=bt,Q[];//Q是队列,元素是二叉树结点指针,容量足够大

if(p==null)return(1);

QueueInit(Q);QueueIn(Q,p);//初始化队列,根结点指针入队

while(!QueueEmpty(Q))

{p=QueueOut(Q);//出队

i

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论