
{
struct student *p1,*p2
p1=NUllp2=head
while(p2!=NULL&&stu->num>p2->num){
p1=p2
p2=p2->next
}
if(p1==NULL) head=stu
else p1->next=stu
stu->next=p2
retuen head
}
前两天作为作业,我也编了一个学生动态链表,供你参考。程序在VC++2005上编译、运行通过,链表部分使用的是标准算法。
//by 兔弟蛇哥
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define NL printf("\n")
#define CLS system("CLS")
#define PAUSE system("PAUSE")
#define EMPTYLINE while(getchar()!='\n')
#define MAX_STDUENT_NUM 50 //当前允许的最大学生数以及允许的最大学号
struct student{
int number
char name[50]
float mark[4] //分别表示语文、数学、英语、总分
struct student *next
}
struct student *Head
int StudentNum
struct student *Head_Orderly[4]
void GO(int)
void PrintStu(struct student *)
struct student* Creat(struct student*)
void SearchOrderly(int,struct student *,struct student **,struct student**)
int SeachStdNum(int,struct student *)
float InputNum(char *,int,int,char *)
int InputYN(void)
struct student* SearchStuByName(char [],struct student *)
struct student* SearchStuByNum(int,struct student *)
int DeleteByNum(int,struct student **)
int DeleteByName(char [],struct student **)
struct student *BeOrdered(struct student *,int)
void main()
{
Head=NULL
StudentNum=0 //已输入的学生总数
int k,choice
for(k=0k<4k++)
Head_Orderly[k]=NULL
while(1){
printf("**********学生成绩动态链表示意程序**********\n\n")
printf("当前设定的最大学生数:%d\n",MAX_STDUENT_NUM)
printf("当前设定的学号范围:1-%d\n",MAX_STDUENT_NUM)
printf("1 输入新的学生数据\n")
printf("2 删除指定学生数据\n")
printf("3 查询学生成绩信息\n")
printf("0 退出\n")
NL NL
choice=(int)InputNum("请选择:",0,3,"int")
GO(choice)
}
}
void GO(int choice){
struct student *T,*p
int number,choice2,choice3
char name[50]
switch(choice){
case 0: exit(EXIT_SUCCESS)
case 1:
case 2: {NL NL
if(Head==NULL){
printf("很遗憾,链表中没有学生!\n")
return
}
printf("1 按姓名\n")
printf("2 按学号\n")
printf("3 返回\n")
NL NL
choice2=(int)InputNum("请选择:",1,3,"int")
switch(choice2){
case 3: return
case 1: {printf("请输入要删除的学生姓名:")
scanf("%s",name)
DeleteByName(name,&Head)
break
}
case 2: {
number=(int)InputNum("请输入要删除的学生学号:",1,MAX_STDUENT_NUM,"int")
DeleteByNum(number,&Head)
break
}
}
break
}
case 3: {NL NL
if(Head==NULL){
printf("很遗憾,链表中没有学生!\n")
return
}
printf("1 查询全部\n")
printf("2 按姓名查询\n")
printf("3 按学号查询\n")
printf("4 按语文分数排序\n")
printf("5 按数学分数排序\n")
printf("6 按英语分数排序\n")
printf("7 按总分分数排序\n")
printf("8 返回\n")
NL NL
choice3=(int)InputNum("请选择:",1,8,"int")
if(choice3==8) return
if(choice3==1)
if(choice3==2){printf("请输入要查询的学生姓名:")
scanf("%s",name)
p=SearchStuByName(name,Head)
if(p==NULL)
printf("无此学生!\n\n")
else{
T=(struct student*)malloc(sizeof(struct student))
*T=*p
T->next=NULL
PrintStu(T)
}
return
}
if(choice3==3){
number=(int)InputNum("请输入要查询的学生学号:",1,MAX_STDUENT_NUM,"int")
p=SearchStuByNum(number,Head)
if(p==NULL)
printf("无此学生!\n\n")
else{
T=(struct student*)malloc(sizeof(struct student))
*T=*p
T->next=NULL
PrintStu(T)
}
return
}
Head_Orderly[choice3-4]=BeOrdered(Head,choice3-4)
PrintStu(Head_Orderly[choice3-4])
return
}
}
}
void PrintStu(struct student *head)
{
struct student *p
int i=0
p=head
printf("序号\t学号\t姓名\t语文\t数学\t英语\t总分\n")
while(p!=NULL){
printf("%d\t%d\t%s\t%.1f\t%.1f\t%.1f\t%.1f\n",++i,p->number,&p->name,p->mark[0],p->mark[1],p->mark[2],p->mark[3])
p=p->next
}
NL NL
PAUSE
NL NL
return
}
struct student* Creat(struct student *head) //新建或插入链表
{
struct student *p,*u,*v//p:新建表元指针;v,u:查询时的当前表元和前驱表元的指针
p=u=v=NULL
/*创建新表元*/
while(1){
if(StudentNum==MAX_STDUENT_NUM){
printf("学生已输满!\n\n")
return head
}
p=(struct student*)malloc(sizeof(struct student))
while(1){
p->number=(int)InputNum("学号:",1,MAX_STDUENT_NUM,"int")
if(head==NULL||SeachStdNum(p->number,head)==0) break//检查学号是否重复(允许不顺序输入学号)
printf("学号重复!请重输:")
}
printf("请输入姓名:")
scanf("%s",p->name)
p->mark[0]=InputNum("语文成绩:",0,100,"float")
p->mark[1]=InputNum("数学成绩:",0,100,"float")
p->mark[2]=InputNum("英语成绩:",0,100,"float")
p->mark[3]=p->mark[0]+p->mark[1]+p->mark[2]
p->next=NULL
/*按学号顺序插入新表元*/
if(head==NULL) head=p
else{
SearchOrderly(p->number,head,&v,&u)
if(v==NULL) head=p
else v->next=p
p->next=u
}
StudentNum++
printf("添加成功!现有学生:%d人。\n",StudentNum)
printf("是否继续(Y/N)?")
if(InputYN()==0) return head
}
}
void SearchOrderly(int num,struct student *head,struct student **v,struct student **u)
{
struct student *u1,*v1
v1=NULL
u1=head
while(u1!=NULL&&num>u1->number){
v1=u1
u1=u1->next
}
*v=v1
*u=u1
return
}
int SeachStdNum(int num,struct student *head)
{
struct student *p
p=head
while(p!=NULL&&p->number!=num)
p=p->next
if(p==NULL) return 0
else return 1
}
float InputNum(char *string,int range_min,int range_max,char *mode)
{
char temp[10]
int i
int err
char mode1[]="int"
union{
int a
float b
}input
for(){
err=0
printf("%s",string)
scanf("%10s",temp)
EMPTYLINE
if(strlen(temp)>4) continue
for(i=0temp[i]!='\0'i++)
if((isdigit(temp[i])==0&&temp[i]!='.')||(isdigit(temp[i])==0&&strcmp(mode1,mode)==0)) err=1
if(err) continue
if(strcmp(mode1,mode)==0){
input.a=atoi(temp)
if(input.a>=range_min&&input.a<=range_max)
return (float)input.a
}
else{
input.b=atof(temp)
if(input.b>=(float)range_min&&input.b<=(float)range_max)
return input.b
}
}
}
int InputYN() //检查输入。(N(n)或Y(y))
{
char t[3]
while(1){
scanf("%2s",&t)
EMPTYLINE
if(t[1]) printf("输入的字符过多!")
else if(t[0]=='Y'||t[0]=='y') return 1
else if(t[0]=='N'||t[0]=='n') return 0
else printf("输入有误!")
NL
printf("请重新输入:")
}
}
struct student* SearchStuByName(char name[],struct student *head)
{
struct student *p
p=head
while(p!=NULL){
if(strcmp(name,p->name)==0) return p
p=p->next
}
return NULL
}
struct student* SearchStuByNum(int Num,struct student *head)
{
struct student *p
p=head
while(p!=NULL){
if(p->number==Num) return p
p=p->next
}
return NULL
}
int DeleteByNum(int Num,struct student **head)
{
struct student *v,*u
u=v=NULL
SearchOrderly(Num,*head,&v,&u)
if(u==NULL||u->number!=Num){
printf("找不到此学号的学生!删除失败。")
NL NL
return 1
}
if(v==NULL) *head=u->next
else v=u->next
u->next=NULL
free(u)
StudentNum--
printf("删除成功!现在链表中共有%d位学生。",StudentNum)
NL NL
return 0
}
int DeleteByName(char name[],struct student **head)
{
struct student *v,*u
v=NULL
u=*head
while(u!=NULL&&strcmp(u->name,name)){
v=u
u=u->next
}
if(u==NULL){
printf("找不到此姓名的学生!删除失败。")
NL NL
return 1
}
if(v==NULL) *head=u->next
else v=u->next
u->next=NULL
free(u)
StudentNum--
printf("删除成功!现在链表中共有%d位学生。",StudentNum)
NL NL
return 0
}
struct student *BeOrdered(struct student *head,int mode)
{
struct student *newhead,*p,*newp,*u,*v,*u2
int i
p=head
newhead=u=v=NULL
while(p!=NULL){
newp=(struct student*)malloc(sizeof(struct student))
*newp=*p
newp->next=NULL
if(newhead==NULL) newhead=newp
else{
v=NULLu=newhead
while(u!=NULL&&newp->mark[mode]<u->mark[mode]){
v=u
u2=u
u=u->next
}
if(newp->mark[mode]==u2->mark[mode]){ //如果该科成绩相等,依次以语文、数学、英语的顺序排序
for(i=0i<3i++){
if(newp->mark[mode]>u->mark[mode]){
v=u
u=u->next
break
}
}
}
if(v==NULL) newhead=newp
else v->next=newp
newp->next=u
}
p=p->next
}
return newhead
}
#include <stdio.h>typedef struct Link/*双向链表结构体*/
{
int data
struct Link *lift
struct Link *right
}linkx,*linky
linky Init()/*建立双向链表*/
void PrLink(linky p)/*输出双向链表*/
linky Sort(linky head)/*对双向链表排序*/
linky Swap(linky head,linky one,linky two)/*任意交换双向链表两个结点的地址*/
void main(void)
{
linky head
head=Init()
head=Sort(head)
PrLink(head)
}
linky Init()/*建立链表*/
{
linky p,q,head
int n=0
head=p=q=(linky)malloc(sizeof(linkx))
clrscr()
printf("please input 10 num: ")
scanf("%d",&p->data)/*输入数据*/
head->lift=NULL
n++
while(n!=10)/*一直输入到规定的数字个数停止*/
{
q=p
p=(linky)malloc(sizeof(linkx))
scanf("%d",&p->data)/*输入数据*/
q->right=p
p->lift=q
n++
}
p->right=NULL
return(head)
}
linky Swap(linky head,linky one,linky two)/*任意交换两个结点*/
{linky temp
if(one->lift==NULL&&two->right==NULL)/*首和尾巴的交换*/
{
if(one->right==two)/*只有两个结点的情况下*/
{
two->right=one
two->lift=NULL
one->lift=two
one->right=NULL
head=two
}
else/*有间隔的首尾交换*/
{
one->right->lift=two
two->lift->right=one
two->right=one->right
one->lift=two->lift
two->lift=one->right=NULL
head=two/*尾结点成为头结点*/
}
}
else if(two->right==NULL)/*尾和任意一个交换*/
{
if(one->right==two)/*交换最后两个结点*/
{
one->lift->right=two
two->lift=one->lift
two->right=one
one->lift=two
one->right=NULL
}
else/*和前面其他结点交换*/
{
temp=two->lift
temp->right=one
one->lift->right=two
one->right->lift=two
two->lift=one->lift
two->right=one->right
one->lift=temp
one->right=NULL
}
}
else if(one->lift==NULL)/*头和任意一个交换*/
{
if(one->right==two)/*交换头两个结点*/
{
two->right->lift=one
one->right=two->right
one->lift=two
two->right=one
two->lift=NULL
head=two
}
else/*头结点和后面其他结点交换*/
{
temp=one->right
temp->lift=two
one->lift=two->lift
one->right=two->right
two->lift->right=one
two->right->lift=one
two->right=temp
two->lift=NULL
head=two/*交换的结点成为头结点*/
}
}
else/*当中的任意两个交换*/
{
if(one->right==two)/*交换连在一起的两个结点*/
{
temp=one->lift
one->lift->right=two
one->right->lift=two
one->lift=two
one->right=two->right
two->right->lift=one
two->right=one
two->lift=temp
}
else/*交换隔开的两个结点*/
{
one->lift->right=two
one->right->lift=two
one->lift=two->lift
temp=one->right
one->right=two->right
two->lift->right=one
two->right->lift=one
two->right=temp
two->lift=one->lift
}
}
return(head)
}
linky Sort(linky head)/*对链表排序*/
{
linky i,j,t,p
int max
p=head
for(i=pi->right!=NULLi=i->right)/*用选择法的思想对这些结点排序*/
{
max=i->data
for(j=i->rightj!=NULLj=j->right)
if(j->data<max)
{
max=j->data
t=j
}
if(max!=i->data)/*如果没有找到比i小的结点*/
{
head=Swap(head,i,t)/*因为最终返回的是头结点,而头结点又有可能变化,所以每次头结点返回*/
i=t
}
}
return(head)
}
void PrLink(linky p)/*输出链表*/
{
linky q
printf("Now the link: ")
do
{
q=p
printf("%d ",p->data)
p=p->right
free(q)/*释放输出结点*/
}
while(p!=NULL)
getch()
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)