BST 存储结构建立(插入)、删除、 查找算法的实现及应用

(一)下面的代码要实现的任务:

1.设计 BST 的左右链存储结构;

  2.实现 BST 左右链存储结构上的插入(建立)、删除、查找和排序算法。

3.利用 BST 结构和相应的操作算法,实现班级学习成绩管理(单科成绩管理, 排名;加权绩点管理与排名等)

4.学生的基础成绩信息以文件形式保存;学生基础成绩信息和排名信息以文件形式存储;并能显示到屏幕。

(二)话不多说上代码:

#include <stdio.h>
#include <stdlib.h>
#include <io.h>
#include <math.h>
#include <time.h>

#define maxsize 100

typedef struct StuInfo
{
   char name[100][100];
   //char obj1[100][100];
   int sco1[100];
   //char obj2[100][100];
   int sco2[100];
   int avi[100];
  // char scoAve[100][100];
}StuInfo;

typedef struct BSTN
{
    int data;
   // struct StuInfo stu;
     char name1[100];
    // int sco1[100];
     int sco21;
     int sco11;
     int scoAv1;

    struct BSTN *lchild,*rchild;
}BSTN,*BstTree;
//全局变量写文件
char keep[100][10];
int cou=0;
char s1[10][5];
char s2[10][5];
char sa[10][5];
char *zhengti;
//查找,放在建立前面

int search(BstTree T,BstTree f,BstTree *p,int key)/* 指针f指向T的双亲,其初始调用值为NULL */
{
    if(!T)
    {
        *p=f;
        return -1;
    }
    else if(key==T->data)
    {
        *p=T;
        return 0;
    }
    else if(key<T->data)
        return search(T->lchild,T,p,key);
     else
        return search(T->rchild,T,p,key);
}

//插入
int insert(BstTree *T,int score1,char ss[],int score2,int aveScore,int cho)
{
    int key;
    BstTree p,s;
    if (cho==1)
        key=score1;
        else
            key=aveScore;
    if(search(*T,NULL,&p,key)==-1)
    {
        s=(BstTree)malloc(sizeof(BSTN));
        s->data=key;
        //s->name1=s[];
        strcpy(s->name1,ss);
        s->sco11=score1;
        s->sco21=score2;
        s->scoAv1=aveScore;
        s->lchild=s->rchild=NULL;
            	//printf("aa");
        if(!p)
            *T=s;//插入S为新的根结点
        else if(key<p->data)
            p->lchild=s;
        else
            p->rchild=s;
        return 0;

    }
    else
        return -1;

}


int Delete(BstTree *p)
{
	BstTree q,s;
	if((*p)->rchild==NULL) /* 右子树空则只需重接它的左子树(待删结点是叶子也走此分支) */
	{
		q=*p; *p=(*p)->lchild; free(q);
	}
	else if((*p)->lchild==NULL) /* 只需重接它的右子树 */
	{
		q=*p; *p=(*p)->rchild; free(q);
	}
	else /* 左右子树均不空 */
	{
		q=*p; s=(*p)->lchild;
		while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
		{
			q=s;
			s=s->rchild;
		}
		(*p)->data=s->data; /*  s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值) */
		if(q!=*p)
			q->rchild=s->lchild; /*  重接q的右子树 */
		else
			q->lchild=s->lchild; /*  重接q的左子树 */
		free(s);
	}
	return 1;
}

/* 若二叉排序树T中存在关键字等于key的数据元素时,则删除该数据元素结点, */
/* 并返回TRUE;否则返回FALSE。 */
int DeleteBST(BstTree *T,int key)
{
	if(!*T) /* 不存在关键字等于key的数据元素 */
		return -1;
	else
	{
		if (key==(*T)->data) /* 找到关键字等于key的数据元素 */
			return Delete(T);
		else if (key<(*T)->data)
			return DeleteBST(&(*T)->lchild,key);
		else
			return DeleteBST(&(*T)->rchild,key);

	}
}

void PreOrderTraverse(BstTree T)
{
	if(T==NULL)
		return;

	printf("%d",T->data);/* 显示结点数据,可以更改为其它对结点操作 */
	PreOrderTraverse(T->lchild); /* 再先序遍历左子树 */
	PreOrderTraverse(T->rchild); /* 最后先序遍历右子树 */
}

/* 初始条件: 二叉树T存在 */
/* 操作结果: 中序递归遍历T */
void InOrderTraverse(BstTree T)
{
	if(T==NULL)
		return  ;
	/**/
	InOrderTraverse(T->lchild); /* 中序遍历左子树 */
	printf("%s\t",T->name1);
    store(T);
	printf("%d\t",T->sco11);
	printf("%d\t",T->sco21);
	printf("%d\n",T->scoAv1);
	/* 显示结点数据,可以更改为其它对结点操作 */
	InOrderTraverse(T->rchild); /* 最后中序遍历右子树 */
}

void store(BstTree T)
{
    int i;
    for(i=0;i<strlen(T->name1);i++)
    {
        keep[cou][i]=T->name1[i];
    }
        //keep[cou][i]=T->sco11;
        //itoa(T->sco11,keep[cou][i],10);
    //keep[cou]=T->name1;
    itoa(T->sco11,s1[cou],10);
	itoa(T->sco21,s2[cou],10);
	itoa(T->scoAv1,sa[cou],10);
   // printf("%s",keep[cou]);
	//sa[cou]=T->scoAv1;
	//wriIn(s1);
	cou++;

	//printf("%d",cou);
}
void andstr()
{
    int i;
    for(i=0;i<10;i++)
    {
        //strcat(zhengti,keep[i]);
        zhengti=keep[i];
    }
}
void wriIn(int whi)
{
    //if(whi==1)
    FILE *pFile = fopen("F:\\untitled\\DataStructure\\实验\\实验二\\aac.txt", "w"); // 文件打开方式 如果原来有内容也会销毁
   /* else
        FILE *pFile = fopen("F:\\untitled\\DataStructure\\实验\\实验二\\aac.txt", //打开文件的名称
    "w");*/
    int i;
    fprintf(pFile,"%s","按工数排序\n");
    fprintf(pFile,"%s","姓名\t工数\t概率论\t绩点\n");
    for(i=0;i<10;i++)
    {
        fprintf(pFile,"%s",keep[i]);
         fprintf(pFile,"\t");
        fprintf(pFile,"%s",s1[i]);
         fprintf(pFile,"\t");
         fprintf(pFile,"%s",s2[i]);
        fprintf(pFile,"\t");
         fprintf(pFile,"%s",sa[i]);
       fprintf(pFile,"\n");

    }
    fclose(pFile);

}
void wriIn2(int whi)
{
    //if(whi==1)
    FILE *pFile = fopen("F:\\untitled\\DataStructure\\实验\\实验二\\aab.txt", "w"); // 文件打开方式 如果原来有内容也会销毁
   /* else
        FILE *pFile = fopen("F:\\untitled\\DataStructure\\实验\\实验二\\aac.txt", //打开文件的名称
    "w");*/
    int i;
     fprintf(pFile,"%s","按绩点排序\n");
    fprintf(pFile,"%s","姓名\t工数\t概率论\t绩点\n");
    for(i=0;i<10;i++)
    {
        fprintf(pFile,"%s",keep[i]);
         fprintf(pFile,"\t");
        fprintf(pFile,"%s",s1[i]);
         fprintf(pFile,"\t");
         fprintf(pFile,"%s",s2[i]);
        fprintf(pFile,"\t");
         fprintf(pFile,"%s",sa[i]);
       fprintf(pFile,"\n");

    }
    fclose(pFile);

}

int main(void)
{
	int i,hahahaha;
	int a[10]={62,88,58,47,35,73,51,99,94,37};
	BstTree T=NULL;
	BstTree T1=NULL;
	StuInfo stu;
   // read(stu);
    FILE *in;
	int LINE = 128,len,j=50,k=0,m;
	char buf[LINE],ss[50][j];
	in = fopen("F:\\untitled\\DataStructure\\实验\\实验二\\aaa.txt", "r");
	if (in == NULL) {
		printf("找不到该文件");

	} else {



        fgets(buf, LINE, in);
		while(fgets(buf, LINE, in) != NULL) {
			len = strlen(buf);
			for(m=0;m<len;m++){

			ss[k][m]=buf[m];
			ss[k][m+1]='\0';
			//printf("%c",ss[k][m]);
			}
			k++;
			//printf("\n");
		}
	}
	 char delims[] = " ";

	int count,a2;
    char *t;
//a1=0;
    for(a2=0;a2<k;a2++){


	t= strtok(ss[a2], delims);
	for(count=0;count<strlen(t);count++)
    {
       stu.name[a2][count]=t[count];
       // printf("%c", stu.name[a1][count]);
    }
    //a1++;

    t = strtok(NULL, delims);
    stu.sco1[a2]=atoi(t);
	//printf("%d", stu.sco1[a1]+1);
   // a1++;

    t = strtok(NULL, delims);
    stu.sco2[a2]=atoi(t);
         }

        double ave[10];
	for(i=0;i<10;i++)
	{
        ave[i]=(((int)(stu.sco1[i]*5+stu.sco2[i]*4)/9)*100.00)/100.00;
        stu.avi[i]=ave[i];
		insert(&T, stu.sco1[i],stu.name[i],stu.sco2[i],stu.avi[i],1);
		insert(&T1, stu.sco1[i],stu.name[i],stu.sco2[i],stu.avi[i],2);
		//printf("%lf",ave[i]);
		//printf("%d??\n",stu.sco1[i]);
	}
	//for(i=0;i<10;)
	/*printf("\n前序遍历二叉树:");
	PreOrderTraverse(T);*/
	printf("请选择相关操作:1.按工数排序;2:按绩点排序;3:结束\n");
	//do{
	scanf("%d",&hahahaha);
	if(hahahaha==1){
	printf("\n按工数排序:\n");
	InOrderTraverse(T);
	wriIn(hahahaha);
	//hahahaha=2;
	}
	cou=0;
	if(hahahaha==2){
		printf("\n按绩点排序:\n");
	InOrderTraverse(T1);
	wriIn2(hahahaha);}//}while(hahahaha==3);
	//if(hahahaha==3)
	return 0;
}

    原文作者:查找算法
    原文地址: https://blog.csdn.net/idevede/article/details/50659727
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞