int LeafKlevel(BiTree bt, int k) //求二叉树bt 的第k(k>1) 层上叶子结点个数 {if(bt==null || k<1) return(0);
BiTree p=bt,Q[]; //Q是队列,元素是二叉树结点指针,容量足够大
int front=0,rear=1,leaf=0; //front 和rear是队头和队尾指针, leaf是叶子结点数 int last=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(level>k) return (leaf); //层数大于k 后退出运行 }//while }//结束LeafKLevel
2、 将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,则为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。
int BPGraph (AdjMatrix g)
//判断以邻接矩阵表示的图g是否是二部图。
{int s[]; //顶点向量,元素值表示其属于那个集合(值1和2表示两个集合) int Q[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。
int f=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(f {visited[v]=1; //确保对每一个顶点,都要检查与其邻接点不应在一个集合中 for (j=1,j<=n;j++) if (g[v][j]==1){if (!s[j]) {s[j]=jh; Q[++r]=j;} //邻接点入队列 else if (s[j]==s[v]) return(0);} //非二部图 }//if (!visited[v]) }//while return(1); }//是二部图 [算法讨论] 题目给的是连通无向图,若非连通,则算法要修改。 3、假设以I和O分别表示入栈和出栈操作。栈的初态和终态均为空,入栈和出栈的操作序列可表示为仅由I和O组成的序列,称可以操作的序列为合法序列,否则称为非法序列。(15分) (1)A和D是合法序列,B和C 是非法序列。 (2)设被判定的操作序列已存入一维数组A中。 int Judge(char A[]) //判断字符数组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(k>j){printf(“序列非法\\n”);exit(0);} } i++; //不论A[i]是‘I’或‘O’,指针i均后移。} if(j!=k) {printf(“序列非法\\n”);return(false);} else {printf(“序列合法\\n”);return(true);} }//算法结束。 4、约瑟夫环问题(Josephus问题)是指编号为1、2、„,n的n(n>0)个人按顺时针方向围坐成一圈,现从第s个人开始按顺时针方向报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,„,如此重复直到所有的人全部出列为止。现要求采用循环链表结构设计一个算法,模拟此过程。 #include typedef listnode *linklist; void jose(linklist head,int s,int m) {linklist k1,pre,p; int count=1; pre=NULL; k1=head; /*k1为报数的起点*/ while (count!=s) /*找初始报数起点*/ {pre=k1; k1=k1->next; count++; } while(k1->next!=k1) /*当循环链表中的结点个数大于1时*/ { p=k1; /*从k1开始报数*/ count=1; while (count!=m) /*连续数m个结点*/ { pre=p; p=p->next; count++; } pre->next=p->next; /*输出该结点,并删除该结点*/ printf(\"%4d\ free(p); k1=pre->next; /*新的报数起点*/ } printf(\"%4d\输出最后一个结点*/ free(k1); } main() {linklist head,p,r; int n,s,m,i; printf(\"n=\"); scanf(\"%d\ printf(\"s=\"); scanf(\"%d\ printf(\"m=\ scanf(\"%d\ if (n<1) printf(\"n<0\"); else {/*建表*/ head=(linklist)malloc(sizeof(listnode)); /*建第一个结点*/ head->data=n; r=head; for (i=n-1;i>0;i--) /*建立剩余n-1个结点*/ { p=(linklist)malloc(sizeof(listnode)); p->data=i; p->next=head; head=p; } r->next=head; /*生成循环链表*/ jose(head,s,m); /*调用函数*/ } } 5、 将顶点放在两个集合V1和V2。对每个顶点,检查其和邻接点是否在同一个集合中,如是,则为非二部图。为此,用整数1和2表示两个集合。再用一队列结构存放图中访问的顶点。 int BPGraph (AdjMatrix g) //判断以邻接矩阵表示的图g是否是二部图。 {int s[]; //顶点向量,元素值表示其属于那个集合(值1和2表示两个集合) int Q[];//Q为队列,元素为图的顶点,这里设顶点信息就是顶点编号。 int f=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(f {visited[v]=1; //确保对每一个顶点,都要检查与其邻接点不应在一个集合中 for (j=1,j<=n;j++) if (g[v][j]==1){if (!s[j]) {s[j]=jh; Q[++r]=j;} //邻接点入队列 else if (s[j]==s[v]) return(0);} //非二部图 }//if (!visited[v]) }//while return(1); }//是二部图 [算法讨论] 题目给的是连通无向图,若非连通,则算法要修改。 6、 连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,若不再连通,则将该边恢复。若仍连通,继续向下删;直到剩n-1条边为止。 void SpnTree (AdjList g) //用“破圈法”求解带权连通无向图的一棵最小代价生成树。 {typedef struct {int i,j,w}node; //设顶点信息就是顶点编号,权是整型数 node edge[]; scanf( \"%d%d\输入边数和顶点数。 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].w {edge[k].w=0; eg--; }//测试下一条边edge[k],权值置0表示该边被删除 k++; //下条边 }//while }//算法结束。 connect()是测试图是否连通的函数,可用图的遍历实现, 7、设有一组初始记录关键字序列(K1,K2,„,Kn),要求设计一个算法能够在O(n)的时间复杂度内将线性表划分成两部分,其中左半部分的每个关键字均小于Ki,右半部分的每个关键字均大于等于Ki。 void quickpass(int r[], int s, int t) { int i=s, j=t, x=r[s]; while(i 因篇幅问题不能全部显示,请点此查看更多更全内容