学生信息管理系统C实现

      最近看了一些数据结构的书,感觉看书的时候看一段时间就感到厌倦了,个人觉得光看书枯燥无味而且也没多大收获,倒不如丢开书本自己写代码,遇到不会的再看书或请教别人,于是决定写一些代码,也算是我学了数据结构的劳动成果吧。代码不多,1000行左右。其中有些代码是照搬别人的,但85%以上的代码还是我个人写的,说实话,写这些代码确实觉得很累,为了完成这段代码,请教了不少CSDN的网友,今天我就把代码贴出来,代码我也不想修改了,注释也没写多少,毕竟个人能力有限,再说这些代码也没多大实际意义,希望对于那些初学数据结构的朋友们能有所帮助,也希望高手能指点一二。

      好了,废话也不多说了,直接把代码贴出来算了。这是一个小的不能再小的学生信息管理系统。

 

                            该系统的主要功能图

  /*
 * studamdin.c
 *
 *  Created on: 2010-5-18
 *      Author: Richard
 */
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>

typedef struct student *stud;
struct student {
 char num[20]; //学号
 char name[20]; //姓名
 int age; //年龄
 int score; //分数
 char pnum[20]; //电话号码
 stud next;
};

char *getnum(); //获得学生学号并判断其合法性
char *getname(); //获得学生姓名并判断其合法性
int getage(); //获得学生年龄并判断其合法性
int getscore(); //获得学生分数并判断其合法性
char *getpnum(); //获得学生电话号码并判断其合法性
void StudInit(stud *head); //链表初始化
void InsertAtHead(stud head, stud p0); //头插法
void InsertAtMid(stud head, stud p0, int(*compare)(stud, stud)); //中间插法
void InsertAtTail(stud head, stud p0); //尾插法
void InsertAtPos(stud head, int i, stud p0); //插在指定位置
void Insert(stud head); //向链表中插入记录
int Length(stud head); //获得链表长度
void keyboard(stud head); //通过键盘录入记录
void file(stud head); //通过文件录入记录
void input(stud head); //录入记录
int SearchByMember(stud head, stud p0, int(*compare)(stud, stud));//通过结构体成员查找
stud SearchByPos(stud head, int i); //通过位置查找
void Search(stud head); //查找记录
void DeleteByPos(stud head, int i); //通过位置删除
void DeleteByMember(stud head, stud p0, int(*compare)(stud, stud)); //通过结构体成员删除
void DeleteDuplicate(stud head, int(*compare)(stud, stud)); //删除重复记录
void DeleteAll(stud head); //删除所有记录
void Delete(stud head); //删除记录
void Viewall(stud head); //输出链表
void Reverse(stud head); //反向输出链表
void Savetofile(stud head); //输出链表到文件
void Output(stud head); //输出链表
int Cmpnum(stud p1, stud p2); //比较学号
int Cmpname(stud p1, stud p2); //比较姓名
int Cmpage(stud p1, stud p2); //比较年龄
int Cmpscore(stud p1, stud p2); //比较成绩
int Cmppnum(stud p1, stud p2); //比较电话号码
void InsertionSortLink(stud *ListHead, stud ListEnd, int(*compare)(stud, stud)); //插入排序
void
xQuickSortL(stud *ListHead, stud ListEnd, int N, int(*compare)(stud, stud)); //随机快速排序
void Sort(stud head); //排序
stud Getonerec(stud head); //获得一条记录
stud Getonenode(); //产生一个结点


int Cmpnum(stud p1, stud p2) {
 return strcmp(p1->num, p2->num);
}

int Cmpname(stud p1, stud p2) {
 return strcmp(p1->name, p2->name);
}

int Cmpage(stud p1, stud p2) {
 return p1->age - p2->age;
}

int Cmpscore(stud p1, stud p2) {
 return p1->score - p2->score;
}

int Cmppnum(stud p1, stud p2) {
 return strcmp(p1->pnum, p2->pnum);
}

char *getnum() {
 char *number = malloc(20), *head = "071080", *p;
 memset(number, '/0', 20);
 while (1) {
  printf("请输入学生学号,必须以071080开头,长度为8,全为数字,输入0结束/n");
  scanf("%s", number);
  if (strcmp(number, "0") == 0)
   break;
  if (strlen(number) == 8 && strncmp(number, head, 6) == 0) {
   for (p = number; *p != '/0' && isdigit(*p); p++)
    ;
   if (*p == '/0')
    break;
  }
  printf("输入不合法!请重试!/n");
 }
 return number;
}

char *getname() {
 char *name = malloc(20), *p;
 memset(name, '/0', 20);
 while (1) {
  printf("请输入学生姓名,必须全为字母,长度为1~20/n");
  scanf("%s", name);
  //getchar();
  for (p = name; *p != '/0' && isprint(*p) && !iscntrl(*p)
    && !isdigit(*p); p++)
   ;
  if (*p == '/0')
   break;
  printf("输入不合法!请重试!/n");
 }
 return name;
}

int getage() {
 char *sage = malloc(20), *p;
 int age;
 memset(sage, '/0', 20);
 while (1) {
  printf("请输入学生年龄,必须为1~100之间的整数/n");
  scanf("%s", sage);
  //getchar();
  for (p = sage; *p != '/0' && isdigit(*p); p++)
   ;
  if (*p == '/0') {
   age = atoi(sage);
   if (age > 0 && age <= 100)
    break;
  }
  printf("输入不合法,请重试!/n");
 }
 return age;
}

int getscore() {
 int score;
 char *sscore = malloc(20), *p;
 memset(sscore, '/0', 20);
 while (1) {
  printf("请输入学生成绩,必须为0~100的整数/n");
  scanf("%s", sscore);
  //getchar();
  for (p = sscore; *p != '/0' && isdigit(*p); p++)
   ;
  if (*p == '/0') {
   score = atoi(sscore);
   if (score >= 0 && score <= 100)
    break;
  }
  printf("输入不合法,请重试!/n");
 }
 return score;
}

char *getpnum() {
 char *number = malloc(20), *p;
 memset(number, '/0', 20);
 while (1) {
  printf("请输入电话号码,必须全为数字,长度为11/n");
  scanf("%s", number);
  //getchar();
  if (strlen(number) == 11) {
   for (p = number; *p != '/0' && isdigit(*p); p++)
    ;
   if (*p == '/0')
    break;
  }
  printf("输入不合法,请重试!/n");
 }
 return number;
}

void StudInit(stud *head) {
 if ((*head = (stud) malloc(sizeof(struct student))) == NULL) {
  printf("分配内存出错!/n");
  exit(-1);
 }
 (*head)->next = NULL;
}

int Length(stud head) {
 if (head->next == NULL)
  return 0;
 else {
  int i = 0;
  stud p = head->next;
  while (p) {
   i++;
   p = p->next;
  }
  return i;
 }
}

void InsertAtHead(stud head, stud p0) {
 p0->next = head->next;
 head->next = p0;
}

void InsertAtTail(stud head, stud p0) {
 if (head->next == NULL)
  InsertAtHead(head, p0);
 else {
  stud p = head->next;
  while (p->next != NULL)
   p = p->next;
  p0->next = p->next;
  p->next = p0;
 }
}

void InsertAtMid(stud head, stud p0, int(*compare)(stud, stud)) {
 if (head->next == NULL)
  InsertAtHead(head, p0);
 else {
  stud p = head->next, p1 = head;
  while ((*compare)(p0, p) > 0 && p->next != NULL) {
   p1 = p;
   p = p->next;
  }
  if (p->next == NULL)
   InsertAtTail(head, p0);
  else if (p1 == head)
   InsertAtHead(head, p0);
  else {
   p0->next = p1->next;
   p1->next = p0;
  }
 }
}

void InsertAtPos(stud head, int i, stud p0) {
 int j;
 stud p = head;
 if (i == Length(head) + 1) {
  InsertAtTail(head, p0);
 } else if (i == 1) {
  InsertAtHead(head, p0);
 } else {
  for (j = 1; j <= i - 1; j++)
   p = p->next;
  p0->next = p->next;
  p->next = p0;
 }
}

void Insert(stud head) {
 int i, j;
 stud p0;
 while (1) {
  printf("/t/t/t插入记录/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("9.返回主菜单/n");
  printf("请选择(1~9)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtHead(head, p0);
    printf("成功插入该记录!/n");
   }
   break;
  case 2:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtTail(head, p0);
    printf("成功插入该记录!/n");
   }
   break;
  case 3:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtMid(head, p0, Cmpnum);
    printf("成功插入该记录!/n");
   }
   break;
  case 4:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtMid(head, p0, Cmpname);
    printf("成功插入该记录!/n");
   }
   break;
  case 5:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtMid(head, p0, Cmpage);
    printf("成功插入该记录!/n");
   }
   break;
  case 6:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtMid(head, p0, Cmpscore);
    printf("成功插入该记录!/n");
   }
   break;
  case 7:
   p0 = Getonerec(head);
   if (p0 == NULL)
    printf("你输入了不合法的记录!/n");
   else {
    InsertAtMid(head, p0, Cmppnum);
    printf("成功插入该记录!/n");
   }
   break;
  case 8:
   printf("请输入要插入的位置/n");
   scanf("%d", &j);
   getchar();
   if (j < 1 || j > Length(head) + 1)
    printf("插入位置不合法!/n");
   else {
    p0 = Getonerec(head);
    if (p0 == NULL)
     printf("你输入了不合法的记录!/n");
    else {
     InsertAtPos(head, j, p0);
     printf("成功插入该记录!/n");
    }
   }
   break;
  case 9:
   return;
   break;
  default:
   printf("输入不合法,请重试!/n");
  }
 }
}

void keyboard(stud head) {
 char *num, *name, *pnum;
 int age, score;
 stud p0, p = Getonenode();
 while (1) {
  num = getnum();
  strcpy(p->num, num);
  if (strcmp(num, "0") == 0 || SearchByMember(head, p, Cmpnum)) {
   printf("学号为0或该学号已存在!已有记录如上!/n");
   return;
  }
  pnum = getpnum();
  strcpy(p->pnum, pnum);
  if (SearchByMember(head, p, Cmppnum)) {
   printf("该电话号码已存在!已有记录如上!/n");
   return;
  } else {
   name = getname();
   age = getage();
   score = getscore();
   p0 = (stud) malloc(sizeof *p0);
   strcpy(p0->num, num);
   strcpy(p0->name, name);
   p0->age = age;
   p0->score = score;
   strcpy(p0->pnum, pnum);
   InsertAtTail(head, p0);
  }
 }
}

stud Getonenode() {
 stud p = malloc(sizeof *p);
 memset(p->name, '/0', 20);
 memset(p->num, '/0', 20);
 memset(p->pnum, '/0', 20);
 p->age = 0;
 p->score = 0;
 p->next = NULL;
 return p;
}

stud Getonerec(stud head) {
 printf("输入一条记录/n");
 char *num, *name, *pnum;
 int age, score;
 stud p0, p = Getonenode();
 num = getnum();
 strcpy(p->num, num);
 if (strcmp(num, "0") == 0 || SearchByMember(head, p, Cmpnum)) {
  printf("学号为0或该学号已存在!已有记录如上:/n");
  return NULL;
 }
 pnum = getpnum();
 strcpy(p->pnum, pnum);
 if (SearchByMember(head, p, Cmppnum)) {
  printf("该电话号码已存在!已有记录如上:/n");
  return NULL;
 } else {
  name = getname();
  age = getage();
  score = getscore();
  p0 = (stud) malloc(sizeof *p0);
  strcpy(p0->num, num);
  strcpy(p0->name, name);
  p0->age = age;
  p0->score = score;
  strcpy(p0->pnum, pnum);
 }
 return p0;
}

void file(stud head) {
 FILE *fp;
 char filepath[20];
 stud p, p0 = Getonenode();
 char *num = malloc(20), *name = malloc(20), *pnum = malloc(20);
 int score, age;
 printf("请输入文件路径名:/n");
 scanf("%s", filepath);
 //getchar();
 if ((fp = fopen(filepath, "r")) == NULL) {
  printf("不能找到该文件:%s/n", filepath);
  return;
 }
 printf("以下记录为重复记录:/n");
 while (fscanf(fp, "%s %s %d %d %s", num, name, &age, &score, pnum) != EOF) {
  strcpy(p0->num, num);
  strcpy(p0->pnum, pnum);
  if (strcmp(num, "0") != 0 && !SearchByMember(head, p0, Cmpnum)
    && !SearchByMember(head, p0, Cmppnum)) {
   p = (stud) malloc(sizeof(*p));
   strcpy(p->num, num);
   strcpy(p->name, name);
   strcpy(p->pnum, pnum);
   p->score = score;
   p->age = age;
   InsertAtTail(head, p);
  }
 }
 fclose(fp);
 printf("成功录入记录!/n");
}

void input(stud head) {
 int i;
 while (1) {
  printf("/t/t/t录入记录/n");
  printf("1.从键盘录入/n");
  printf("2.从文件录入/n");
  printf("3.返回主菜单/n");
  printf("请选择(1~3)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   keyboard(head);
   break;
  case 2:
   file(head);
   break;
  case 3:
   return;
   break;
  default:
   printf("输入不合法,请重试!");
  }
 }
}

int SearchByMember(stud head, stud p0, int(*compare)(stud, stud)) {
 if (head->next == NULL)
  return 0;
 stud p = head->next;
 int i = 0;
 for (; p; p = p->next)
  if ((*compare)(p, p0) == 0) {
   printf("%s/t%s/t%d/t%d/t%s/n", p->num, p->name, p->age, p->score,
     p->pnum);
   i++;
  }
 return i;
}

stud SearchByPos(stud head, int i) {
 if (head->next == NULL)
  return NULL;
 if (i < 1 && i > Length(head))
  return NULL;
 int j;
 stud p = head;
 for (j = 1; p && j <= i; j++)
  p = p->next;
 return p;
}

void Search(stud head) {
 int i, j, age, score;
 char *num, *name, *pnum;
 stud p, p0 = Getonenode();
 while (1) {
  printf("/t/t查找指定记录/n");
  printf("1.根据学号查找/n");
  printf("2.根据姓名查找/n");
  printf("3.根据年龄查找/n");
  printf("4.根据成绩查找/n");
  printf("5.根据电话号码查找/n");
  printf("6.根据位置查找/n");
  printf("7.返回主菜单/n");
  printf("请选择(1~7)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   num = getnum();
   strcpy(p0->num, num);
   printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
   j = SearchByMember(head, p0, Cmpnum);
   if (j == 0)
    printf("没有相关记录!/n");
   else
    printf("一共有%d条相关记录!/n", j);
   break;
  case 2:
   name = getname();
   strcpy(p0->name, name);
   printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
   j = SearchByMember(head, p0, Cmpname);
   if (j == 0)
    printf("没有相关记录!/n");
   else
    printf("一共有%d条相关记录!/n", j);
   break;
  case 3:
   age = getage();
   p0->age = age;
   printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
   j = SearchByMember(head, p0, Cmpage);
   if (j == 0)
    printf("没有相关记录!/n");
   else
    printf("一共有%d条相关记录!/n", j);
   break;
  case 4:
   score = getscore();
   p0->score = score;
   printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
   j = SearchByMember(head, p0, Cmpscore);
   if (j == 0)
    printf("没有相关记录!/n");
   else
    printf("一共有%d条相关记录!/n", j);
   break;
  case 5:
   pnum = getpnum();
   strcpy(p0->pnum, pnum);
   printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
   j = SearchByMember(head, p0, Cmppnum);
   if (j == 0)
    printf("没有相关记录!/n");
   else
    printf("一共有%d条相关记录!/n", j);
   break;
  case 6:
   printf("请输入位置/n");
   scanf("%d", &j);
   getchar();
   p = SearchByPos(head, j);
   if (p) {
    printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
    printf("%s/t%s/t%d/t%d/t%s/n", p->num, p->name, p->age,
      p->score, p->pnum);
   } else {
    printf("没有相关记录/n");
   }
   break;
  case 7:
   return;
   break;
  default:
   printf("输入不合法,请重试!/n");
  }
 }
}

void DeleteByPos(stud head, int i) {
 if (SearchByPos(head, i) == NULL) {
  printf("没有该记录!");
  return;
 } else {
  stud p = head->next, p1 = head, p0 = SearchByPos(head, i);
  while (p != p0) {
   p1 = p;
   p = p->next;
  }
  p1->next = p->next;
  free(p);
  printf("成功删除该记录!/n");
 }
}

void DeleteByMember(stud head, stud p0, int(*compare)(stud, stud)) {
 if (head->next == NULL || SearchByMember(head, p0, *compare) == 0) {
  printf("没有该记录,无法删除!/n");
  return;
 } else {
  stud p, q = head, t;
  for (p = head->next; p != NULL; p = t) {
   t = p->next;
   if ((*compare)(p, p0) == 0) {
    q->next = p->next;
    free(p);
   } else
    q = p;
  }
  printf("成功删除记录以上记录!/n");
 }
}

void DeleteDuplicate(stud head, int(*compare)(stud, stud)) {
 stud p, q, r, t;
 p = head->next;
 while (p) {
  r = p->next;
  q = p;
  for (; r; r = t) {
   t = r->next;
   if ((*compare)(p, r) == 0) {
    q->next = r->next;
    free(r);
   } else
    q = r;
  }
  p = p->next;
 }
}

void DeleteAll(stud head) {
 if (head->next == NULL) {
  printf("没有记录,无法删除!/n");
  return;
 } else {
  stud p, p1;
  for (p = head->next; p; p = p1) {
   p1 = p->next;
   free(p);
  }
  printf("成功删除所有记录!/n");
 }
}

void Delete(stud head) {
 int i, j;
 char *num, *pnum, *name;
 int age, score;
 stud p0 = Getonenode();
 while (1) {
  printf("/t/t/t删除指定记录/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("9.删除成绩相同的记录(仅保留一条)/n");
  printf("10.删除所有记录/n");
  printf("11.返回主菜单/n");
  printf("请选择(1~11)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   num = getnum();
   strcpy(p0->num, num);
   DeleteByMember(head, p0, Cmpnum);
   break;
  case 2:
   pnum = getpnum();
   strcpy(p0->pnum, pnum);
   DeleteByMember(head, p0, Cmppnum);
   break;
  case 3:
   printf("请输入位置/n");
   scanf("%d", &j);
   getchar();
   DeleteByPos(head, j);
   break;
  case 4:
   name = getname();
   strcpy(p0->name, name);
   DeleteByMember(head, p0, Cmpname);
   break;
  case 5:
   age = getage();
   p0->age = age;
   DeleteByMember(head, p0, Cmpage);
   break;
  case 6:
   score = getscore();
   p0->score = score;
   DeleteByMember(head, p0, Cmpscore);
   printf("成功删除记录!/n");
   break;
  case 7:
   DeleteDuplicate(head, Cmpname);
   printf("成功删除重复记录!/n");
   break;
  case 8:
   DeleteDuplicate(head, Cmpage);
   printf("成功删除重复记录!/n");
   break;
  case 9:
   DeleteDuplicate(head, Cmpscore);
   printf("成功删除重复记录!/n");
   break;
  case 10:
   DeleteAll(head);
   break;
  case 11:
   return;
   break;
  default:
   printf("输入不合法,请重试!/n");
  }
 }
}

void Viewall(stud head) {
 if (head->next == NULL) {
  printf("没有记录!/n");
  return;
 } else {
  stud p;
  printf("学生学号/t学生姓名/t学生年龄/t学生成绩/t电话号码/n");
  for (p = head->next; p; p = p->next)
   printf("%s/t%s/t%d/t%d/t%s/n", p->num, p->name, p->age, p->score,
     p->pnum);
 }
}

void Reverse(stud head) {
 if (head == NULL)
  return;
 stud p1, p2;
 p1 = head->next;
 head->next = NULL;
 while (p1) {
  p2 = p1->next;
  p1->next = head->next;
  head->next = p1;
  p1 = p2;
 }
}

void Savetofile(stud head) {
 if (head->next == NULL) {
  printf("记录为空!/n");
  return;
 } else {
  FILE *fp;
  stud p = head->next;
  char filepath[20];
  printf("请输入文件路径名:/n");
  scanf("%s", filepath);
  //getchar();
  if ((fp = fopen(filepath, "w+")) == NULL) {
   printf("不能打开文件%s!/n", filepath);
   return;
  } else {
   while (p) {
    fprintf(fp, "%s %s %d %d %s/n", p->num, p->name, p->age,
      p->score, p->pnum);
    p = p->next;
   }
   fclose(fp);
  }
 }
}

void output(stud head) {
 int i;
 while (1) {
  printf("/t/t/t输出记录及保存至文件/n");
  printf("1.查看所有记录/n");
  printf("2.反向查看所有记录/n");
  printf("3.保存至文件/n");
  printf("4.返回主菜单/n");
  printf("请选择(1~4)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   Viewall(head);
   break;
  case 2:
   Reverse(head);
   Viewall(head);
   break;
  case 3:
   Savetofile(head);
   printf("成功保存该记录!/n");
   break;
  case 4:
   return;
   break;
  default:
   printf("输入不合法,请重新输入!/n");
  }
 }
}

void InsertionSortLink(stud *ListHead, stud ListEnd, int(*compare)(stud, stud)) {
 stud newlist, walk, save;
 newlist = ListEnd;
 walk = *ListHead;
 for (; walk != ListEnd; walk = save) {
  stud *pnewlink;
  for (pnewlink = &newlist; *pnewlink != ListEnd && (*compare)(walk,
    *pnewlink) >= 0; pnewlink = &((*pnewlink)->next))
   ;
  save = walk->next;
  walk->next = *pnewlink;
  *pnewlink = walk;
 }
 *ListHead = newlist;
}

void xQuickSortL(stud *ListHead, stud ListEnd, int N, int(*compare)(stud, stud)) {
 int left_count, right_count, npivot;
 stud *left_walk, pivot, old;
 stud *right_walk, right;
 while (N > 1) {
  if (N <= 9) {
   InsertionSortLink(ListHead, ListEnd, *compare);
   break;
  }
  npivot = abs(rand()) % N;
  if (npivot < 2 || npivot > N - 2)
   npivot = 2;
  old = *ListHead;
  while (npivot--)
   old = old->next;
  pivot = old->next;
  old->next = pivot->next;
  left_walk = ListHead;
  right_walk = &right;
  left_count = right_count = 0;
  for (old = *ListHead; old != ListEnd; old = old->next) {
   if ((*compare)(old, pivot) < 0) {
    left_count += 1;
    *left_walk = old;
    left_walk = &(old->next);
   } else {
    right_count += 1;
    *right_walk = old;
    right_walk = &(old->next);
   }
  }
  *right_walk = ListEnd;
  *left_walk = pivot;
  pivot->next = right;
  if (left_count > right_count) {
   xQuickSortL(&(pivot->next), ListEnd, right_count, *compare);
   ListEnd = pivot;
   N = left_count;
  } else {
   xQuickSortL(ListHead, pivot, left_count, *compare);
   ListHead = &(pivot->next);
   N = right_count;
  }
 }
}

void Sort(stud head) {
 if (head->next == NULL) {
  printf("没有记录,无法排序!/n");
  return;
 } else if (head->next->next == NULL) {
  printf("只有一条记录,无须排序!/n");
 }
 while (1) {
  printf("/t/t/t记录排序/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("9.根据电话号码升序排序/n");
  printf("10.根据电话号码降序排序/n");
  printf("11.返回主菜单/n");
  printf("请选择(1~11)/n");
  int N = Length(head), i;
  stud p = head->next;
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   xQuickSortL(&p, NULL, N, Cmpnum);
   head->next = p;
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 2:
   xQuickSortL(&p, NULL, N, Cmpnum);
   head->next = p;
   Reverse(head);
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 3:
   xQuickSortL(&p, NULL, N, Cmpname);
   head->next = p;
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 4:
   xQuickSortL(&p, NULL, N, Cmpname);
   head->next = p;
   Reverse(head);
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 5:
   xQuickSortL(&p, NULL, N, Cmpage);
   head->next = p;
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 6:
   xQuickSortL(&p, NULL, N, Cmpage);
   head->next = p;
   Reverse(head);
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 7:
   xQuickSortL(&p, NULL, N, Cmpscore);
   head->next = p;
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 8:
   xQuickSortL(&p, NULL, N, Cmpscore);
   head->next = p;
   Reverse(head);
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 9:
   xQuickSortL(&p, NULL, N, Cmppnum);
   head->next = p;
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 10:
   xQuickSortL(&p, NULL, N, Cmppnum);
   head->next = p;
   Reverse(head);
   printf("排序后的结果为:/n");
   Viewall(head);
   break;
  case 11:
   return;
   break;
  default:
   printf("输入不合法,请重试!/n");
  }
 }
}

int main() {
 stud head;
 StudInit(&head);
 int i;
 while (1) {
  printf("/t/t/t欢迎使用本人制作的学生信息管理系统/n");
  printf("1.录入记录/n");
  printf("2.插入记录/n");
  printf("3.查找记录/n");
  printf("4.删除记录/n");
  printf("5.查看记录及保存/n");
  printf("6.记录排序/n");
  printf("7.退出/n");
  printf("请选择(1~7)/n");
  scanf("%d", &i);
  getchar();
  switch (i) {
  case 1:
   input(head);
   break;
  case 2:
   Insert(head);
   break;
  case 3:
   Search(head);
   break;
  case 4:
   Delete(head);
   break;
  case 5:
   output(head);
   break;
  case 6:
   Sort(head);
   break;
  case 7:
   return 0;
   break;
  default:
   printf("输入不合法,请重试!/n");
  }
 }
 return 0;
}

参考书籍

[1] 陈锐. 零基础学数据结构[M]. 北京:机械工业出版社,2010

[2] 谭浩强. C程序设计(第三版)[M]. 北京:清华大学出版社,2005

[3] 宋劲杉. Linux C编程一站式学习[M]. 北京:电子工业出版社,2009

[4] []罗伯特 赛奇威克, 算法:C语言实现(第1~4部分)[M]. 霍红卫译. 北京:机械工业出版社,2009

[5] []Andrew BinStockJohn Rex. 程序员实用算法[M]. 陈宗斌译. 北京:机械工业出版社,2009

[6] 陈先在,张丽萍. Linux C函数实例速查手册[M]. 北京:人民邮电出版社,2009

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值