c语言机试题及答案_第1页
c语言机试题及答案_第2页
c语言机试题及答案_第3页
c语言机试题及答案_第4页
c语言机试题及答案_第5页
已阅读5页,还剩120页未读 继续免费阅读

下载本文档

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

文档简介

c语言机试题及答案一、基础编程题(30分)1.学生成绩管理系统(15分)请编写一个C语言程序,实现一个简单的学生成绩管理系统。系统需要实现以下功能:1.添加学生信息(包括学号、姓名、三门课程成绩)2.显示所有学生信息3.根据学号查询学生信息4.计算每个学生的平均分5.按平均分从高到低排序学生信息输入输出要求:1.程序运行后,首先显示一个菜单,包含上述5个功能选项,以及退出选项。2.用户通过输入数字选择功能。3.添加学生信息时,需要输入学号、姓名和三门课程成绩。4.显示学生信息时,需要格式化输出,包括学号、姓名、三门课程成绩和平均分。5.查询学生信息时,输入学号后显示该学生的所有信息。6.排序功能需要将学生按照平均分从高到低排序后显示。评分标准:1.程序能够正确实现所有功能(10分)2.代码结构清晰,注释适当(3分)3.用户界面友好,输入输出格式规范(2分)2.文件操作与数据处理(15分)请编写一个C语言程序,实现文件操作与数据处理功能:1.从一个文本文件中读取整数数据,文件中每行包含一个整数。2.统计文件中整数的个数,并计算它们的总和、平均值、最大值和最小值。3.将统计结果写入另一个文本文件中。4.同时,将文件中的所有整数按从小到大的顺序排序,并将排序后的结果写入第三个文本文件中。输入输出要求:1.程序需要指定输入文件名、统计结果输出文件名和排序结果输出文件名。2.统计结果文件应包含整数个数、总和、平均值、最大值和最小值。3.排序结果文件应包含排序后的整数,每行一个。评分标准:1.文件操作正确,能够正确读取和写入文件(8分)2.数据处理算法正确,统计结果准确(4分)3.排序算法实现正确(3分)二、算法实现题(40分)3.链表操作(20分)请实现一个双向链表,并完成以下操作:1.创建链表节点结构体,包含整数值和前后指针。2.实现链表的创建、插入、删除、查找功能。3.实现链表的逆序功能。4.实现链表的合并功能:将两个已排序的链表合并为一个有序链表。输入输出要求:1.程序应提供菜单界面,用户可以选择不同的操作。2.插入操作可以指定位置或按顺序插入。3.删除操作可以指定删除某个值的节点或按位置删除。4.查找操作可以查找某个值是否存在并返回位置。5.逆序操作将链表中的节点顺序反转。6.合并操作接受两个已排序的链表,返回合并后的有序链表。评分标准:1.双向链表的基本操作实现正确(10分)2.逆序和合并算法实现正确(8分)3.代码结构清晰,注释适当(2分)4.二叉树遍历与操作(20分)请实现一个二叉树,并完成以下操作:1.创建二叉树节点结构体,包含整数值和左右子节点指针。2.实现二叉树的创建、插入、删除功能。3.实现二叉树的前序、中序、后序遍历,并输出结果。4.实现二叉树的层序遍历。5.计算二叉树的深度和叶子节点数量。输入输出要求:1.程序应提供菜单界面,用户可以选择不同的操作。2.插入操作可以按特定规则插入节点(例如二叉搜索树规则)。3.删除操作可以删除指定值的节点,并保持二叉搜索树的性质。4.各种遍历操作应输出遍历结果。5.计算深度和叶子节点数量并输出结果。评分标准:1.二叉树的基本操作实现正确(10分)2.各种遍历算法实现正确(6分)3.深度和叶子节点计算算法正确(4分)三、综合应用题(30分)5.简易图书管理系统(30分)请设计并实现一个简易图书管理系统,该系统需要具备以下功能:1.图书信息管理:包括添加图书、删除图书、修改图书信息、查询图书。2.借阅管理:包括借书、还书、查看借阅记录。3.用户管理:包括添加用户、删除用户、修改用户信息。4.数据持久化:将图书、用户和借阅记录保存到文件中,并在程序启动时加载。图书信息应包括:图书ID、书名、作者、出版社、出版年份、库存数量。用户信息应包括:用户ID、姓名、联系方式。借阅记录应包括:借阅ID、图书ID、用户ID、借阅日期、应还日期、实际归还日期(如果已归还)。输入输出要求:1.程序启动后显示主菜单,包含图书管理、借阅管理、用户管理等选项。2.各个子功能也应有相应的菜单界面。3.所有数据操作都应提供友好的用户界面。4.程序退出时,所有数据应自动保存到文件中。评分标准:1.系统功能完整,能够实现所有要求的功能(15分)2.数据结构设计合理,代码结构清晰(8分)3.文件操作正确,数据持久化实现良好(7分)标准答案及解析题目1:学生成绩管理系统标准答案:```cinclude<stdio.h>include<stdlib.h>include<string.h>defineMAX_STUDENTS100//学生结构体typedefstruct{intid;//学号charname[50];//姓名floatscore1;//课程1成绩floatscore2;//课程2成绩floatscore3;//课程3成绩floataverage;//平均分}Student;//全局变量Studentstudents[MAX_STUDENTS];intstudentCount=0;//函数声明voidaddStudent();voiddisplayAllStudents();voidsearchStudent();voidcalculateAverage();voidsortStudents();voiddisplayMenu();//添加学生信息voidaddStudent(){if(studentCount>=MAX_STUDENTS){printf("学生数量已达上限,无法添加更多学生!\n");return;}Students;printf("请输入学号:");scanf("%d",&s.id);printf("请输入姓名:");scanf("%s",);printf("请输入课程1成绩:");scanf("%f",&s.score1);printf("请输入课程2成绩:");scanf("%f",&s.score2);printf("请输入课程3成绩:");scanf("%f",&s.score3);s.average=(s.score1+s.score2+s.score3)/3.0;students[studentCount++]=s;printf("学生信息添加成功!\n");}//显示所有学生信息voiddisplayAllStudents(){if(studentCount==0){printf("没有学生信息可显示!\n");return;}printf("\n%-10s%-20s%-10s%-10s%-10s%-10s\n","学号","姓名","课程1","课程2","课程3","平均分");printf("------------------------------------------------------------\n");for(inti=0;i<studentCount;i++){printf("%-10d%-20s%-10.2f%-10.2f%-10.2f%-10.2f\n",students[i].id,students[i].name,students[i].score1,students[i].score2,students[i].score3,students[i].average);}}//根据学号查询学生信息voidsearchStudent(){if(studentCount==0){printf("没有学生信息可查询!\n");return;}intid;printf("请输入要查询的学生学号:");scanf("%d",&id);intfound=0;for(inti=0;i<studentCount;i++){if(students[i].id==id){printf("\n%-10s%-20s%-10s%-10s%-10s%-10s\n","学号","姓名","课程1","课程2","课程3","平均分");printf("------------------------------------------------------------\n");printf("%-10d%-20s%-10.2f%-10.2f%-10.2f%-10.2f\n",students[i].id,students[i].name,students[i].score1,students[i].score2,students[i].score3,students[i].average);found=1;break;}}if(!found){printf("未找到学号为%d的学生!\n",id);}}//计算每个学生的平均分voidcalculateAverage(){if(studentCount==0){printf("没有学生信息可计算!\n");return;}for(inti=0;i<studentCount;i++){students[i].average=(students[i].score1+students[i].score2+students[i].score3)/3.0;}printf("已计算所有学生的平均分!\n");}//按平均分从高到低排序学生信息voidsortStudents(){if(studentCount==0){printf("没有学生信息可排序!\n");return;}//使用冒泡排序for(inti=0;i<studentCount-1;i++){for(intj=0;j<studentCount-i-1;j++){if(students[j].average<students[j+1].average){Studenttemp=students[j];students[j]=students[j+1];students[j+1]=temp;}}}printf("学生信息已按平均分从高到低排序!\n");}//显示菜单voiddisplayMenu(){printf("\n==========学生成绩管理系统==========\n");printf("1.添加学生信息\n");printf("2.显示所有学生信息\n");printf("3.根据学号查询学生信息\n");printf("4.计算每个学生的平均分\n");printf("5.按平均分从高到低排序学生信息\n");printf("0.退出系统\n");printf("=====================================\n");printf("请选择操作:");}intmain(){intchoice;do{displayMenu();scanf("%d",&choice);switch(choice){case1:addStudent();break;case2:displayAllStudents();break;case3:searchStudent();break;case4:calculateAverage();break;case5:sortStudents();displayAllStudents();break;case0:printf("感谢使用学生成绩管理系统,再见!\n");break;default:printf("无效的选择,请重新输入!\n");}}while(choice!=0);return0;}```解析:1.数据结构设计:使用结构体`Student`来存储学生信息,包括学号、姓名、三门课程成绩和平均分。使用数组`students`来存储所有学生信息,并使用`studentCount`记录当前学生数量。2.功能实现:-`addStudent()`:添加学生信息,输入学号、姓名和三门课程成绩,并计算平均分。-`displayAllStudents()`:格式化输出所有学生信息。-`searchStudent()`:根据学号查询并显示学生信息。-`calculateAverage()`:计算所有学生的平均分。-`sortStudents()`:使用冒泡排序按平均分从高到低排序学生信息。3.用户界面:`displayMenu()`函数显示菜单选项,`main()`函数处理用户输入并调用相应的功能函数。常见错误分析:1.数组越界:在添加学生时,没有检查`studentCount`是否已达到`MAX_STUDENTS`,可能导致数组越界。解决方案:在添加学生前检查`studentCount`是否小于`MAX_STUDENTS`。2.内存泄漏:如果使用动态内存分配(如`malloc`)来存储学生信息,但没有在程序结束时释放内存,会导致内存泄漏。解决方案:在程序结束时使用`free`释放所有动态分配的内存。3.输入缓冲区问题:使用`scanf`读取字符串时,如果输入包含空格,可能会导致读取不完整。解决方案:使用`fgets`读取整行,然后使用`sscanf`或`strtok`等函数解析数据。4.排序算法错误:实现排序算法时,可能会出现比较条件错误或交换逻辑错误。解决方案:仔细检查排序算法的比较条件和交换逻辑,可以使用简单的测试数据验证算法的正确性。实务操作提示:1.模块化设计:将不同功能实现为独立的函数,提高代码的可读性和可维护性。2.输入验证:对用户输入进行验证,确保输入的数据类型和范围正确。3.错误处理:对可能出现的错误情况进行处理,如文件打开失败、内存分配失败等。4.代码注释:为代码添加适当的注释,解释关键算法和复杂逻辑。5.测试用例:编写测试用例,验证程序在各种情况下的正确性,包括边界条件和异常情况。题目2:文件操作与数据处理标准答案:```cinclude<stdio.h>include<stdlib.h>include<string.h>//函数声明voidreadDataFromFile(constcharfilename,intdata,intcount);voidcalculateStatistics(intdata,intcount,intsum,floataverage,intmax,intmin);voidwriteStatisticsToFile(constcharfilename,intcount,intsum,floataverage,intmax,intmin);voidsortData(intdata,intcount);voidwriteSortedDataToFile(constcharfilename,intdata,intcount);intmain(){charinputFilename[100],statsFilename[100],sortedFilename[100];intdata=NULL;intcount=0;intsum=0;floataverage=0.0;intmax=0,min=0;//输入文件名printf("请输入输入文件名:");scanf("%s",inputFilename);//读取数据readDataFromFile(inputFilename,&data,&count);if(count==0){printf("文件为空或无法读取文件!\n");return1;}//计算统计信息calculateStatistics(data,count,&sum,&average,&max,&min);//输出统计信息printf("\n数据统计结果:\n");printf("数据个数:%d\n",count);printf("总和:%d\n",sum);printf("平均值:%.2f\n",average);printf("最大值:%d\n",max);printf("最小值:%d\n",min);//输入统计结果文件名printf("\n请输入统计结果输出文件名:");scanf("%s",statsFilename);//写入统计结果writeStatisticsToFile(statsFilename,count,sum,average,max,min);printf("统计结果已写入%s\n",statsFilename);//排序数据sortData(data,count);//输入排序结果文件名printf("\n请输入排序结果输出文件名:");scanf("%s",sortedFilename);//写入排序结果writeSortedDataToFile(sortedFilename,data,count);printf("排序结果已写入%s\n",sortedFilename);//释放内存free(data);return0;}//从文件读取数据voidreadDataFromFile(constcharfilename,intdata,intcount){FILEfile=fopen(filename,"r");if(file==NULL){printf("无法打开文件%s\n",filename);count=0;return;}//计算数据个数inttemp;count=0;while(fscanf(file,"%d",&temp)!=EOF){(count)++;}//重新打开文件fclose(file);file=fopen(filename,"r");if(file==NULL){printf("无法重新打开文件%s\n",filename);count=0;return;}//分配内存data=(int)malloc(countsizeof(int));if(data==NULL){printf("内存分配失败!\n");fclose(file);count=0;return;}//读取数据inti=0;while(fscanf(file,"%d",&(data)[i])!=EOF){i++;}fclose(file);}//计算统计信息voidcalculateStatistics(intdata,intcount,intsum,floataverage,intmax,intmin){sum=0;max=data[0];min=data[0];for(inti=0;i<count;i++){sum+=data[i];if(data[i]>max){max=data[i];}if(data[i]<min){min=data[i];}}average=(float)(sum)/count;}//写入统计结果到文件voidwriteStatisticsToFile(constcharfilename,intcount,intsum,floataverage,intmax,intmin){FILEfile=fopen(filename,"w");if(file==NULL){printf("无法创建文件%s\n",filename);return;}fprintf(file,"数据个数:%d\n",count);fprintf(file,"总和:%d\n",sum);fprintf(file,"平均值:%.2f\n",average);fprintf(file,"最大值:%d\n",max);fprintf(file,"最小值:%d\n",min);fclose(file);}//排序数据(使用冒泡排序)voidsortData(intdata,intcount){for(inti=0;i<count-1;i++){for(intj=0;j<count-i-1;j++){if(data[j]>data[j+1]){inttemp=data[j];data[j]=data[j+1];data[j+1]=temp;}}}}//写入排序结果到文件voidwriteSortedDataToFile(constcharfilename,intdata,intcount){FILEfile=fopen(filename,"w");if(file==NULL){printf("无法创建文件%s\n",filename);return;}for(inti=0;i<count;i++){fprintf(file,"%d\n",data[i]);}fclose(file);}```解析:1.数据读取:`readDataFromFile()`函数首先计算文件中的数据个数,然后分配相应大小的内存,最后读取所有数据到内存中。2.统计计算:`calculateStatistics()`函数计算数据的总和、平均值、最大值和最小值。3.数据排序:`sortData()`函数使用冒泡排序算法对数据进行排序。4.文件写入:`writeStatisticsToFile()`和`writeSortedDataToFile()`函数将统计结果和排序结果分别写入不同的文件。常见错误分析:1.文件打开失败:没有检查文件是否成功打开,导致后续操作失败。解决方案:每次打开文件后检查返回值,如果失败则进行错误处理。2.内存泄漏:分配内存后没有在程序结束时释放,导致内存泄漏。解决方案:使用`malloc`分配内存后,在程序结束时使用`free`释放。3.文件读取错误:使用`fscanf`读取文件时,没有检查返回值,可能导致读取不完整。解决方案:检查`fscanf`的返回值,确保成功读取所有数据。4.排序算法错误:实现排序算法时,可能会出现比较条件错误或交换逻辑错误。解决方案:仔细检查排序算法的比较条件和交换逻辑,可以使用简单的测试数据验证算法的正确性。实务操作提示:1.错误处理:对文件操作、内存分配等可能失败的操作进行错误处理,提高程序的健壮性。2.内存管理:合理分配和释放内存,避免内存泄漏和内存访问越界。3.算法选择:根据数据规模选择合适的排序算法,对于大规模数据,可以考虑使用更高效的排序算法如快速排序或归并排序。4.文件路径:处理文件路径时,注意不同操作系统的路径分隔符差异,可以使用`/`作为跨平台的路径分隔符。5.数据验证:对读取的数据进行验证,确保数据的正确性和有效性。题目3:链表操作标准答案:```cinclude<stdio.h>include<stdlib.h>include<string.h>//链表节点结构体typedefstructNode{intdata;structNodeprev;structNodenext;}Node;//函数声明NodecreateNode(intdata);voidinsertAtEnd(Nodehead,intdata);voidinsertAtPosition(Nodehead,intdata,intposition);voiddeleteByValue(Nodehead,intvalue);voiddeleteByPosition(Nodehead,intposition);intsearchNode(Nodehead,intvalue);voidreverseList(Nodehead);NodemergeSortedLists(Nodelist1,Nodelist2);voiddisplayList(Nodehead);voidfreeList(Nodehead);voiddisplayMenu();//创建新节点NodecreateNode(intdata){NodenewNode=(Node)malloc(sizeof(Node));if(newNode==NULL){printf("内存分配失败!\n");exit(1);}newNode->data=data;newNode->prev=NULL;newNode->next=NULL;returnnewNode;}//在链表末尾插入节点voidinsertAtEnd(Nodehead,intdata){NodenewNode=createNode(data);if(head==NULL){head=newNode;}else{Nodecurrent=head;while(current->next!=NULL){current=current->next;}current->next=newNode;newNode->prev=current;}}//在指定位置插入节点voidinsertAtPosition(Nodehead,intdata,intposition){if(position<0){printf("位置无效!\n");return;}if(position==0){NodenewNode=createNode(data);newNode->next=head;if(head!=NULL){(head)->prev=newNode;}head=newNode;}else{Nodecurrent=head;intcurrentPosition=0;while(current!=NULL&¤tPosition<position-1){current=current->next;currentPosition++;}if(current==NULL){printf("位置超出链表长度!\n");return;}NodenewNode=createNode(data);newNode->next=current->next;newNode->prev=current;if(current->next!=NULL){current->next->prev=newNode;}current->next=newNode;}}//删除指定值的节点voiddeleteByValue(Nodehead,intvalue){if(head==NULL){printf("链表为空!\n");return;}Nodecurrent=head;//如果要删除的是头节点if(current->data==value){head=current->next;if(head!=NULL){(head)->prev=NULL;}free(current);return;}//查找要删除的节点while(current!=NULL&¤t->data!=value){current=current->next;}if(current==NULL){printf("未找到值为%d的节点!\n",value);return;}current->prev->next=current->next;if(current->next!=NULL){current->next->prev=current->prev;}free(current);}//删除指定位置的节点voiddeleteByPosition(Nodehead,intposition){if(head==NULL){printf("链表为空!\n");return;}if(position<0){printf("位置无效!\n");return;}Nodecurrent=head;//如果要删除的是头节点if(position==0){head=current->next;if(head!=NULL){(head)->prev=NULL;}free(current);return;}//查找要删除的节点intcurrentPosition=0;while(current!=NULL&¤tPosition<position){current=current->next;currentPosition++;}if(current==NULL){printf("位置超出链表长度!\n");return;}current->prev->next=current->next;if(current->next!=NULL){current->next->prev=current->prev;}free(current);}//查找节点intsearchNode(Nodehead,intvalue){Nodecurrent=head;intposition=0;while(current!=NULL){if(current->data==value){returnposition;}current=current->next;position++;}return-1;//未找到}//反转链表voidreverseList(Nodehead){if(head==NULL||(head)->next==NULL){return;}Nodecurrent=head;Nodetemp=NULL;while(current!=NULL){//交换prev和next指针temp=current->prev;current->prev=current->next;current->next=temp;//移动到下一个节点(实际上是前一个节点,因为指针已经交换)current=current->prev;}//更新头节点if(temp!=NULL){head=temp->prev;}}//合并两个已排序的链表NodemergeSortedLists(Nodelist1,Nodelist2){Noderesult=NULL;//如果其中一个链表为空,直接返回另一个链表if(list1==NULL){returnlist2;}if(list2==NULL){returnlist1;}//比较两个链表的头节点,较小的作为结果链表的头if(list1->data<=list2->data){result=list1;result->next=mergeSortedLists(list1->next,list2);}else{result=list2;result->next=mergeSortedLists(list1,list2->next);}returnresult;}//显示链表voiddisplayList(Nodehead){if(head==NULL){printf("链表为空!\n");return;}Nodecurrent=head;printf("链表内容:");while(current!=NULL){printf("%d",current->data);current=current->next;}printf("\n");}//释放链表内存voidfreeList(Nodehead){Nodecurrent=head;while(current!=NULL){Nodenext=current->next;free(current);current=next;}}//显示菜单voiddisplayMenu(){printf("\n==========双向链表操作==========\n");printf("1.在链表末尾插入节点\n");printf("2.在指定位置插入节点\n");printf("3.删除指定值的节点\n");printf("4.删除指定位置的节点\n");printf("5.查找节点\n");printf("6.反转链表\n");printf("7.合并两个已排序的链表\n");printf("8.显示链表\n");printf("0.退出\n");printf("===================================\n");printf("请选择操作:");}intmain(){Nodehead=NULL;Nodelist1=NULL,list2=NULL;intchoice,data,position,value;intrunning=1;while(running){displayMenu();scanf("%d",&choice);switch(choice){case1:printf("请输入要插入的整数:");scanf("%d",&data);insertAtEnd(&head,data);printf("节点已插入到链表末尾!\n");break;case2:printf("请输入要插入的整数:");scanf("%d",&data);printf("请输入插入位置:");scanf("%d",&position);insertAtPosition(&head,data,position);break;case3:printf("请输入要删除的值:");scanf("%d",&value);deleteByValue(&head,value);break;case4:printf("请输入要删除的位置:");scanf("%d",&position);deleteByPosition(&head,position);break;case5:printf("请输入要查找的值:");scanf("%d",&value);position=searchNode(head,value);if(position!=-1){printf("值%d在链表中的位置为:%d\n",value,position);}else{printf("未找到值为%d的节点!\n",value);}break;case6:reverseList(&head);printf("链表已反转!\n");break;case7://创建第一个已排序的链表printf("请输入第一个已排序链表的元素个数:");scanf("%d",&data);for(inti=0;i<data;i++){intnum;printf("请输入第%d个元素:",i+1);scanf("%d",&num);insertAtEnd(&list1,num);}//创建第二个已排序的链表printf("请输入第二个已排序链表的元素个数:");scanf("%d",&data);for(inti=0;i<data;i++){intnum;printf("请输入第%d个元素:",i+1);scanf("%d",&num);insertAtEnd(&list2,num);}//合并链表head=mergeSortedLists(list1,list2);printf("两个已排序链表已合并!\n");//释放原始链表的内存freeList(list1);freeList(list2);list1=NULL;list2=NULL;break;case8:displayList(head);break;case0:running=0;break;default:printf("无效的选择,请重新输入!\n");}}//释放链表内存freeList(head);return0;}```解析:1.链表节点结构:使用结构体`Node`表示链表节点,包含整数值和前后指针。2.基本操作:-`createNode()`:创建新节点。-`insertAtEnd()`:在链表末尾插入节点。-`insertAtPosition()`:在指定位置插入节点。-`deleteByValue()`:删除指定值的节点。-`deleteByPosition()`:删除指定位置的节点。-`searchNode()`:查找节点并返回位置。-`reverseList()`:反转链表。-`mergeSortedLists()`:合并两个已排序的链表。3.用户界面:`displayMenu()`函数显示菜单选项,`main()`函数处理用户输入并调用相应的功能函数。常见错误分析:1.内存泄漏:分配内存后没有在程序结束时释放,导致内存泄漏。解决方案:使用`malloc`分配内存后,在程序结束时使用`free`释放。2.指针操作错误:在处理链表指针时,可能会出现指针操作错误,导致程序崩溃。解决方案:仔细检查指针操作,确保指针的有效性。3.边界条件处理:在插入或删除节点时,没有正确处理边界条件(如空链表、头节点、尾节点等)。解决方案:为边界条件编写专门的代码处理逻辑。4.递归深度过大:在合并两个已排序的链表时,使用递归可能会导致递归深度过大,特别是对于长链表。解决方案:可以使用迭代方法代替递归,或者限制递归深度。实务操作提示:1.调试技巧:在链表操作中,可以使用打印语句来跟踪链表的状态,帮助调试。2.内存管理:合理分配和释放内存,避免内存泄漏和内存访问越界。3.边界条件:特别注意处理链表的边界条件,如空链表、只有一个节点的链表等。4.算法优化:对于长链表,可以考虑使用更高效的算法,如迭代代替递归。5.错误处理:对可能出现的错误情况进行处理,如内存分配失败、位置无效等。题目4:二叉树遍历与操作标准答案:```cinclude<stdio.h>include<stdlib.h>include<string.h>//二叉树节点结构体typedefstructTreeNode{intdata;structTreeNodeleft;structTreeNoderight;}TreeNode;//函数声明TreeNodecreateNode(intdata);TreeNodeinsertNode(TreeNoderoot,intdata);TreeNodedeleteNode(TreeNoderoot,intdata);voidpreorderTraversal(TreeNoderoot);voidinorderTraversal(TreeNoderoot);voidpostorderTraversal(TreeNoderoot);voidlevelOrderTraversal(TreeNoderoot);inttreeDepth(TreeNoderoot);intcountLeaves(TreeNoderoot);voiddisplayMenu();//创建新节点TreeNodecreateNode(intdata){TreeNodenewNode=(TreeNode)malloc(sizeof(TreeNode));if(newNode==NULL){printf("内存分配失败!\n");exit(1);}newNode->data=data;newNode->left=NULL;newNode->right=NULL;returnnewNode;}//插入节点(二叉搜索树规则)TreeNodeinsertNode(TreeNoderoot,intdata){if(root==NULL){returncreateNode(data);}if(data<root->data){root->left=insertNode(root->left,data);}elseif(data>root->data){root->right=insertNode(root->right,data);}//如果值已存在,不做任何操作returnroot;}//删除节点TreeNodedeleteNode(TreeNoderoot,intdata){if(root==NULL){returnroot;}//查找要删除的节点if(data<root->data){root->left=deleteNode(root->left,data);}elseif(data>root->data){root->right=deleteNode(root->right,data);}else{//找到要删除的节点//情况1:节点没有子节点或只有一个子节点if(root->left==NULL){TreeNodetemp=root->right;free(root);returntemp;}elseif(root->right==NULL){TreeNodetemp=root->left;free(root);returntemp;}//情况2:节点有两个子节点//获取中序后继(右子树的最小值)TreeNodetemp=root->right;while(temp->left!=NULL){temp=temp->left;}//复制中序后继的值到当前节点root->data=temp->data;//删除中序后继root->right=deleteNode(root->right,temp->data);}returnroot;}//前序遍历voidpreorderTraversal(TreeNoderoot){if(root!=NULL){printf("%d",root->data);preorderTraversal(root->left);preorderTraversal(root->right);}}//中序遍历voidinorderTraversal(TreeNoderoot){if(root!=NULL){inorderTraversal(root->left);printf("%d",root->data);inorderTraversal(root->right);}}//后序遍历voidpostorderTraversal(TreeNoderoot){if(root!=NULL){postorderTraversal(root->left);postorderTraversal(root->right);printf("%d",root->data);}}//层序遍历voidlevelOrderTraversal(TreeNoderoot){if(root==NULL){return;}//使用队列进行层序遍历TreeNodequeue[100];intfront=0,rear=0;//将根节点入队queue[rear++]=root;while(front<rear){//出队并访问节点TreeNodecurrent=queue[front++];printf("%d",current->data);//将左子节点入队if(current->left!=NULL){queue[rear++]=current->left;}//将右子节点入队if(current->right!=NULL){queue[rear++]=current->right;}}}//计算树的深度inttreeDepth(TreeNoderoot){if(root==NULL){return0;}intleftDepth=treeDepth(root->left);intrightDepth=treeDepth(root->right);return(leftDepth>rightDepth?leftDepth:rightDepth)+1;}//计算叶子节点数量intcountLeaves(TreeNoderoot){if(root==NULL){return0;}if(root->left==NULL&&root->right==NULL){return1;}returncountLeaves(root->left)+countLeaves(root->right);}//显示菜单voiddisplayMenu(){printf("\n==========二叉树操作==========\n");printf("1.插入节点\n");printf("2.删除节点\n");printf("3.前序遍历\n");printf("4.中序遍历\n");printf("5.后序遍历\n");printf("6.层序遍历\n");printf("7.计算树的深度\n");printf("8.计算叶子节点数量\n");printf("0.退出\n");printf("=================================\n");printf("请选择操作:");}intmain(){TreeNoderoot=NULL;intchoice,data;intrunning=1;while(running){displayMenu();scanf("%d",&choice);switch(choice){case1:printf("请输入要插入的整数:");scanf("%d",&data);root=insertNode(root,data);printf("节点已插入!\n");break;case2:printf("请输入要删除的整数:");scanf("%d",&data);root=deleteNode(root,data);printf("节点删除操作已完成!\n");break;case3:printf("前序遍历结果:");preorderTraversal(root);printf("\n");break;case4:printf("中序遍历结果:");inorderTraversal(root);printf("\n");break;case5:printf("后序遍历结果:");postorderTraversal(root);printf("\n");break;case6:printf("层序遍历结果:");levelOrderTraversal(root);printf("\n");break;case7:printf("树的深度:%d\n",treeDepth(root));break;case8:printf("叶子节点数量:%d\n",countLeaves(root));break;case0:running=0;break;default:printf("无效的选择,请重新输入!\n");}}//释放树的内存//这里简化处理,实际应用中需要实现一个完整的释放函数while(root!=NULL){root=deleteNode(root,root->data);}return0;}```解析:1.二叉树节点结构:使用结构体`TreeNode`表示二叉树节点,包含整数值和左右子节点指针。2.基本操作:-`createNode()`:创建新节点。-`insertNode()`:按照二叉搜索树的规则插入节点。-`deleteNode()`:删除指定值的节点,并保持二叉搜索树的性质。-`preorderTraversal()`:前序遍历(根-左-右)。-`inorderTraversal()`:中序遍历(左-根-右)。-`postorderTraversal()`:后序遍历(左-右-根)。-`levelOrderTraversal()`

温馨提示

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

评论

0/150

提交评论