从文件读取成本,实现找出最小成本二分检索树的算法,并以树状结构输出
#include
<
stdio.h
>
#include < stdlib.h >
#define N 4
typedef struct te {
int node;
struct te *left,*right;
} tree;
int findmin( int i, int j, int ( * r)[N], int ( * c)[N]);
tree * OBST( int * p, int * q, int n);
void buileTree(tree ** head, int a, int b);
void travseTree(tree * p);
void printTree(tree * head);
void treeToArray(tree * p, int num);
/*
**这里假设数组P和Q都乘了一个相应的整数,使得P和Q的元素值都为整数
*/
char a[N][ 20 ];
int node[ 100 ]; // 用于按顺序保存树中各个结点,以便按树状打印树中结点
int main( void )
{
int p[N],q[N+1],i;
FILE *fp;
tree *head;
if((fp=fopen("cost.txt","r"))==NULL){
printf("Cannot open the file. ");
exit(-1);
}
for(i=0;i<N;i++)
fscanf(fp,"%s",a[i]);
for(i=0;i<N;i++)
fscanf(fp,"%d",&p[i]);
for(i=0;i<N+1;i++)
fscanf(fp,"%d",&q[i]);
for(i=0;i<100;i++) node[i]=-1;
head=OBST(p,q,N);
putchar(' ');
printf("该二分检索树的树状结构如下所示: ");
printTree(head);
system("pause");
return 0;
}
int r[N + 1 ][N + 1 ];
tree * OBST( int * p, int * q, int n) {
int c[N+1][N+1],w[N+1][N+1];//,r[N+1][N+1];
int i,j,m,k;
tree *head;
n++;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
w[i][j]=-1;
c[i][j]=-1;
r[i][j]=-1;
}
for(i=0;i<n-1;i++){
w[i][i]=*(q+i);
r[i][i]=0;
c[i][i]=0;
w[i][i+1]=*(q+i)+*(q+i+1)+*(p+i);
r[i][i+1]=i+1;
c[i][i+1]=w[i][i+1];
}
w[n-1][n-1]=*(q+n-1);
r[n-1][n-1]=0;
c[n-1][n-1]=0;
for(m=2;m<n;m++)
for(i=0;i<n-m;i++){
j=i+m;
w[i][j]=w[i][j-1]+*(p+j-1)+*(q+j);
k=findmin(i,j,r,c);
c[i][j]=w[i][j]+c[i][k-1]+c[k][j];
r[i][j]=k;
}
printf("计算W,C,R的值如下(输出的是他们的逆矩阵)(其中-1表示该数不必考虑): ");
for(j=0;j<n;j++){
for(i=0;i<n;i++)
printf("%2d,%2d,%2d ",w[i][j],c[i][j],r[i][j]);
putchar(' ');
}
buileTree(&head,0,N);
return head;
}
int findmin( int i, int j, int ( * r)[N + 1 ], int ( * c)[N + 1 ]) {
int min,minL,k,m,n;
m=(*(r+i))[j-1];
n=(*(r+i+1))[j];
min=c[i][m-1]+c[m][j];
minL=m;
for(m+=1;m<=n;m++){
k=c[i][m-1]+c[m][j];
if(k<min){
min=k;
minL=m;
}
}
return minL;
}
void buileTree(tree ** p, int a, int b) {
int mk;
if(a==b) return;
mk=r[a][b];
*p=(tree *)malloc(sizeof(tree));
(*p)->node=mk;
(*p)->left=NULL;
(*p)->right=NULL;
buileTree(&(*p)->left,a,mk-1);
buileTree(&(*p)->right,mk,b);
}
void treeToArray(tree * p, int num) {
//将树中的结点按顺序保存到数组中,num表示当前结点的号码,初始调用设为1
if(!p) return;
node[num]=p->node;
treeToArray(p->left,2*num);
treeToArray(p->right,2*num+1);
}
void printTree(tree * head) {
int i,j,level,space,num;
i=1;level=1;num=0;
treeToArray(head,1);
for(i=1,level=1;i<100&&num<N;i++){
if(i==level)
putchar(' ');
space=60/(level+1);
for(j=0;j<space;j++) printf(" ");
if(node[i]!=-1) { printf("%s",a[node[i]-1]); num++;}
else printf(" ");
if((i+1)==level*2) level*=2;
}
putchar(' ');
}
#include < stdlib.h >
#define N 4
typedef struct te {
int node;
struct te *left,*right;
} tree;
int findmin( int i, int j, int ( * r)[N], int ( * c)[N]);
tree * OBST( int * p, int * q, int n);
void buileTree(tree ** head, int a, int b);
void travseTree(tree * p);
void printTree(tree * head);
void treeToArray(tree * p, int num);
/*
**这里假设数组P和Q都乘了一个相应的整数,使得P和Q的元素值都为整数
*/
char a[N][ 20 ];
int node[ 100 ]; // 用于按顺序保存树中各个结点,以便按树状打印树中结点
int main( void )
{
int p[N],q[N+1],i;
FILE *fp;
tree *head;
if((fp=fopen("cost.txt","r"))==NULL){
printf("Cannot open the file. ");
exit(-1);
}
for(i=0;i<N;i++)
fscanf(fp,"%s",a[i]);
for(i=0;i<N;i++)
fscanf(fp,"%d",&p[i]);
for(i=0;i<N+1;i++)
fscanf(fp,"%d",&q[i]);
for(i=0;i<100;i++) node[i]=-1;
head=OBST(p,q,N);
putchar(' ');
printf("该二分检索树的树状结构如下所示: ");
printTree(head);
system("pause");
return 0;
}
int r[N + 1 ][N + 1 ];
tree * OBST( int * p, int * q, int n) {
int c[N+1][N+1],w[N+1][N+1];//,r[N+1][N+1];
int i,j,m,k;
tree *head;
n++;
for(i=0;i<n;i++)
for(j=0;j<n;j++){
w[i][j]=-1;
c[i][j]=-1;
r[i][j]=-1;
}
for(i=0;i<n-1;i++){
w[i][i]=*(q+i);
r[i][i]=0;
c[i][i]=0;
w[i][i+1]=*(q+i)+*(q+i+1)+*(p+i);
r[i][i+1]=i+1;
c[i][i+1]=w[i][i+1];
}
w[n-1][n-1]=*(q+n-1);
r[n-1][n-1]=0;
c[n-1][n-1]=0;
for(m=2;m<n;m++)
for(i=0;i<n-m;i++){
j=i+m;
w[i][j]=w[i][j-1]+*(p+j-1)+*(q+j);
k=findmin(i,j,r,c);
c[i][j]=w[i][j]+c[i][k-1]+c[k][j];
r[i][j]=k;
}
printf("计算W,C,R的值如下(输出的是他们的逆矩阵)(其中-1表示该数不必考虑): ");
for(j=0;j<n;j++){
for(i=0;i<n;i++)
printf("%2d,%2d,%2d ",w[i][j],c[i][j],r[i][j]);
putchar(' ');
}
buileTree(&head,0,N);
return head;
}
int findmin( int i, int j, int ( * r)[N + 1 ], int ( * c)[N + 1 ]) {
int min,minL,k,m,n;
m=(*(r+i))[j-1];
n=(*(r+i+1))[j];
min=c[i][m-1]+c[m][j];
minL=m;
for(m+=1;m<=n;m++){
k=c[i][m-1]+c[m][j];
if(k<min){
min=k;
minL=m;
}
}
return minL;
}
void buileTree(tree ** p, int a, int b) {
int mk;
if(a==b) return;
mk=r[a][b];
*p=(tree *)malloc(sizeof(tree));
(*p)->node=mk;
(*p)->left=NULL;
(*p)->right=NULL;
buileTree(&(*p)->left,a,mk-1);
buileTree(&(*p)->right,mk,b);
}
void treeToArray(tree * p, int num) {
//将树中的结点按顺序保存到数组中,num表示当前结点的号码,初始调用设为1
if(!p) return;
node[num]=p->node;
treeToArray(p->left,2*num);
treeToArray(p->right,2*num+1);
}
void printTree(tree * head) {
int i,j,level,space,num;
i=1;level=1;num=0;
treeToArray(head,1);
for(i=1,level=1;i<100&&num<N;i++){
if(i==level)
putchar(' ');
space=60/(level+1);
for(j=0;j<space;j++) printf(" ");
if(node[i]!=-1) { printf("%s",a[node[i]-1]); num++;}
else printf(" ");
if((i+1)==level*2) level*=2;
}
putchar(' ');
}