2015年辽宁省数据分析深入

更新时间:2023-04-25 01:32:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

1、题目中要求矩阵两行元素的平均值按递增顺序排序,由于每行元素个数相等,按平均值排列与按每行元素之和排列是一个意思。所以应先求出各行元素之和,放入一维数组中,然后选择一种排序方法,对该数组进行排序,注意在排序时若有元素移动,则与之相应的行中各元素也必须做相应变动。

void Translation(float *matrix,int n)

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

{int i,j,k,l;

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

float *p, *pi, *pk;

for(i=0; i

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

for (j=0; j

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

}//for i

for(i=0; i

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

for(j=i+1;j

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

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

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

for(j=0;j

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

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

}//if

}//for i

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

}// Translation

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

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

#include

typedef char datatype;

typedef struct node{

datatype data;

struct node * next;

} listnode;

typedef listnode* linklist;

/*--------------------------------------------*/

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

/*--------------------------------------------*/

linklist deletelist(linklist head)

{ listnode *p,*s,*q;

p=head->next;

while(p)

{s=p;

q=p->next;

while(q)

if(q->data==p->data)

{s->next=q->next;free(q);

q=s->next;}

else

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

q=q->next;

}

p=p->next;

}

return head;

}

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

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

void union(int A[],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(i=0)

if(a[i]

while(i

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

}算法结束

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

(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。BiTree Creat() //建立二叉树的二叉链表形式的存储结构

{ElemType x;BiTree bt;

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

if(x==0) bt=null;

else if(x>0)

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

bt->data=x; bt->lchild=creat(); bt->rchild=creat();

}

else error(“输入错误”);

return(bt);

}//结束 BiTree

int JudgeComplete(BiTree bt) //判断二叉树是否是完全二叉树,如是,返回1,否则,返回0

{int tag=0; BiTree p=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) return 0; //前边已有结点为空,本结点不空

else tag=1; //首次出现结点为空

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

else if (p->rchild) return 0; else tag=1;

} //while

return 1; } //JudgeComplete

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

void Hospital(AdjMatrix w,int n)

//在以邻接带权矩阵表示的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]

m=MAXINT; //设定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算法构造其最小生成树(每选取一条边画一个图)。

6、若第n件物品能放入背包,则问题变为能否再从n-1件物品中选出若干件放入背包(这时背包可放入物品的重量变为s-w[n])。若第n件物品不能放入背包,则考虑从n-1件物品选若干件放入背包(这时背包可放入物品仍为s)。若最终s=0,则有一解;否则,若s<0或虽然s>0但物品数n<1,则无解。

(1)s-w[n],n-1 //Knap(s-w[n],n-1)=true

(2)s,n-1 // Knap←Knap(s,n-1)

7、本题要求建立有序的循环链表。从头到尾扫描数组A,取出A[i](0<=i

LinkedList creat(ElemType A[],int n)

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

{LinkedList h;

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

h->next=h; //形成空循环链表

for(i=0;i

{pre=h;

p=h->next;

while(p!=h && p->data

{pre=p; p=p->next;} //查找A[i]的插入位置

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

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

s->data=A[i]; pre->next=s; s->next=p;//将结点s链入链表中

}

}//for

return(h);

}算法结束

8、本题应使用深度优先遍历,从主调函数进入dfs(v)时,开始记数,若退出dfs()前,已访问完有向图的全部顶点(设为n个),则有向图有根,v为根结点。将n个顶点从1到n编号,各调用一次dfs()过程,就可以求出全部的根结点。题中有向图的邻接表存储结构、记顶点个数的变量、以及访问标记数组等均设计为全局变量。建立有向图g的邻接表存储结构参见上面第2题,这里只给出判断有向图是否有根的算法。

int num=0, visited[]=0 //num记访问顶点个数,访问数组visited初始化。

const n=用户定义的顶点数;

AdjList g ; //用邻接表作存储结构的有向图g。

void dfs(v)

{visited [v]=1; num++; //访问的顶点数+1

if (num==n) {printf(“%d是有向图的根。\n”,v); num=0;}//if

p=g[v].firstarc;

while (p)

{if (visied[p->adjvex]==0) dfs (p->adjvex);

p=p->next;} //while

visited[v]=0; num--; //恢复顶点v

}//dfs

void JudgeRoot()

//判断有向图是否有根,有根则输出之。

{static int i ;

for (i=1;i<=n;i++ ) //从每个顶点出发,调用dfs()各一次。

{num=0; visited[1..n]=0; dfs(i); }

}// JudgeRoot

算法中打印根时,输出顶点在邻接表中的序号(下标),若要输出顶点信息,可使用g[i].vertex。

本文来源:https://www.bwwdw.com/article/6goq.html

Top