學生信息管理系統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

 

 

發佈了28 篇原創文章 · 獲贊 11 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章