单链表实现学生成绩统计,并将男女分离为两个单链表

单链表实现学生成绩统计每个学生包含姓名、性别、学号、成绩的输入,至少输入10个学生,并将成绩按照男女分离形成两个单链表,并对两个单链表进行排序。

C代码运行结果如下:

img

代码:

#define _CRT_SECURE_NO_WARNINGS 1


#include <stdio.h>
#include <stdlib.h>

typedef struct _Student
{
    int id; //学号
    char name[20];//姓名
    char sex; //性别
    int score; //成绩
    struct _Student* next;
}Student;

//初始化链表头
Student* initList(Student* list)
{
    list = (Student*)malloc(sizeof(Student));
    list->next = 0;
    return list;
}

//头插法创建链表
void createList(Student* list)
{
    int i, n;
    Student* t,*p;
    p = list;
    printf("请输入需要插入的学生数量:");
    scanf("%d", &n);
    for (i = 0; i < n; i++)
    {
        t = (Student*)malloc(sizeof(Student));
        t->next = 0;
        printf("请输入第%d个学生的学号:", i + 1);
        scanf("%d", &t->id);
        printf("请输入第%d个学生的姓名:", i + 1);
        scanf("%s", t->name);
        getchar();//吸收回车符
        printf("请输入第%d个学生的性别(F/M):", i + 1);
        scanf("%c", &t->sex);
        printf("请输入第%d个学生的成绩:", i + 1);
        scanf("%d", &t->score);
        
        //插入头插法插入链表
        p->next = t;
        p = t;
    }
    
}

//遍历输出学生信息
void showList(Student* list)
{
    Student* p;
    if (list == 0) return;
    p = list->next;
    while (p)
    {
        printf("%8d  %20s  %c  %3d\n", p->id, p->name, p->sex, p->score);
        p = p->next;
    }
}

//分隔链表
void splitList(Student* plistA, Student* plistB)
{
    Student* pre = plistA;
    Student* p = pre->next;
    Student* pb = plistB;
    
    while (p)
    {
        if (p->sex == 'M')
        {
            pre->next = p->next; //把p从listA中删除

            //把p插入listB
            p->next = 0;
            pb->next = p;
            pb = p;
            //重置p,继续循环
            p = pre->next;
        }
        else
        {
            pre = p;
            p = p->next;
        }
    }
    
}


//根据成绩排序
void sortById(Student* L)
{
    Student* p, * tail, * q;
    tail = NULL;
    while ((L->next->next) != tail)
    {
        p = L;
        q = L->next;
        while (q->next != tail)
        {
            if (q->score > q->next->score) //升序排列 /降序
            {
                p->next = q->next;
                q->next = q->next->next;
                p->next->next = q;
                q = p->next;
            }
            q = q->next;
            p = p->next;
        }
        tail = q;
    }

}




int main()
{
    Student* listA = 0;
    Student* listB = 0;
    listA = initList(listA);
    listB = initList(listB);

    //输入数据并创建链表
    createList(listA);

    showList(listA);
    
    //分成两个链表
    splitList(listA, listB);
    printf("分隔后的女生链表为:\n");
    showList(listA);
    printf("分隔后的男生链表为:\n");
    showList(listB);
    //排序
    
    sortById(listA);
    sortById(listB);
    printf("排序后的女生链表为:\n");
    showList(listA);
    printf("排序后的男生链表为:\n");
    showList(listB);
    
    
    
    return 0;
}

参考一下

# include <stdio.h>
# include <conio.h>
# include <malloc.h>
# include <stdlib.h>
 
struct Node
{
    int num;
    int age;
    char name[30];
    char sex[5];
    int sroce;
    struct Node *next;
};
 
Node *head;
 
Node *Load()                                //载入文件中的数据到结构体中
{
    FILE *fp;  
     Node *cur,*p,*q; 
     cur = NULL; 
     fp = fopen("Student","r");           //以"r"形式打开student的文件 
     if(fp == NULL)                        //如果文件不存在 
     {        
          fp = fopen("Student","w");        //创立一个student文件 
          fclose(fp);                        //关闭文件 
          return cur;                        //返回链表中,存入head 
     } 
     p=(struct Node*)malloc(sizeof(struct Node));     //如果存在 
    if(fread(p,sizeof(struct Node),1,fp) != 1)        //判断文件中的数据 是否只有1个 
        return  cur;                                //是就返回
    cur = p; 
    while(!feof(fp))                                 //否则就开始从文件中读数据 
    {
        q = p; 
        p = (struct Node *)malloc(sizeof(struct Node)); 
        fread(p,sizeof(struct Node),1,fp); 
          q -> next = p; 
    } 
    q -> next = NULL; 
    free(p);                                         //释放指针p所指向的内存空间 
    fclose(fp); 
    return cur;                                         //返回链表中,存入head 
} 
 
void Interface()                                //主界面函数
{
    system( "cls" );                            //清屏函数 
    printf("\n\n\n");
    printf("\t-----------------------------------------------------\n");
    printf("\t-----------------------------------------------------\n");
    printf("\t||                                                 ||\n");
    printf("\t||                     首页                        ||\n");
    printf("\t||                                                 ||\n");
    printf("\t-----------------------------------------------------\n");
    printf("\t-----------------------------------------------------\n");
    printf("\t||                                                 ||\n");
    printf("\t||                                                 ||\n");
    printf("\t||                  ◆1.输入                       ||\n");
    printf("\t||                  ◆2.查询                       ||\n");
    printf("\t||                  ◆3.显示                       ||\n");
    printf("\t||                  ◆4.删除                       ||\n");
    printf("\t||                  ◆5.修改                       ||\n");
    printf("\t||                  ◆0.退出                       ||\n");
    printf("\t||                                                 ||\n");
    printf("\t||                                                 ||\n");
    printf("\t-----------------------------------------------------\n");
    printf("\t-----------------------------------------------------\n");
    return ;
}
 
void Add_Data()                                    //输入学生信息函数
{ 
     Node *p,*q; 
     Node *cur; 
     char flag = '0';      
     cur = (struct Node *)malloc(sizeof(struct Node)); //创建新结点 
     while(flag == '0')                             //输入学生信息 
     {
          q = p = head;
          cur ->next = NULL;
            printf("请输入姓名:");
          scanf("%s",&cur -> name);
          printf("请输入学号:");
          scanf("%d",&cur -> num);
          printf("请输入年龄 :");
          scanf("%d",&cur -> age);
          printf("请输入性别 :");
          scanf("%s",&cur -> sex);
          printf("请输入成绩 :");
          scanf("%d",&cur -> sroce);
            fflush(stdin);                //用来清空输入缓存,以便不影响后面输入的东西
            if(head == NULL)head = cur;    //如果输入的节点是头一个,就把头结点head等于cur 
            else                            //否则在头结点后面加入结点 
            { 
               while(p -> num < cur -> num && p -> next != NULL)    //按学号建立链表
               {
                    q = p;                                            //P节点
                    p = p -> next;                                    //P后一接点
               } 
               if(p -> num > cur -> num)                            //找到head表中的学号大于新建学生的学号,插入学生信息
               {
                   if(p == head)                                    //如果为头结点,前插
                   {
                        cur -> next = head;
                        head = cur;
                   }  
                   else                                                
                   {
                        q -> next = cur;
                        cur -> next = p;
                   } 
                }
                else                                            //找不到比新建学生更大的学号,放在链表最好面
                    p -> next = cur; 
            }   
          cur = (struct Node *)malloc(sizeof(struct Node));     //又创建新结点,为下次输入准备
          printf("输入结束,是否继续输入,按 0 键继续,否者退出.\n");  
            flag = getch();                                        //0就继续输入,其他键就返回主界面 
          fflush(stdin);                                        //清除缓冲区的数据 
     }  
     free(cur);  
     return ;  
}  
 
 
void Find_Data()                                //按学号查找学生信息
{
     Node *p; 
     int num;
     char flag = '0'; 
     bool  mark;
     while(flag == '0') 
     { 
          printf("请输入要查找的学生的学号:  "); 
          scanf("%d",&num);  
          fflush(stdin); 
          mark = false;                            //标记是否找到学生
          p = head;                               //将头结点head赋值与p 
          if(head == NULL)                       //如果链表中头结点为空,则查询错误 
          {
                printf("查询失败.\n");        
                printf("不存在此学生信息.\n");
                return ;
          } 
          else                              //否则开始查询 
          { 
                 while(p != NULL) 
                 { 
                      if(p -> num == num)      //找到学号为num的学生就输出 
                    { 
                        printf("你要查找的学生信息如下:\n"); 
                        printf("学号 :%d\n",p -> num);
                        printf("名字 :%s\n",p -> name);
                        printf("性别 :%s\n",p -> sex);
                        printf("年龄 :%d\n",p -> age);
                        printf("成绩 :%d\n",p -> sroce); 
                        mark = true;  
                        break; 
                    } 
                      else 
                        p = p -> next; 
                } 
          } 
          if(!mark)                                    //没找到学生与num匹配的学生 
          {
               printf("查询失败.\n");        
               printf("不存在此学生信息.\n"); 
               return ;
          } 
          printf("查找结束,是否继续查找,按 0 键继续,否者退出.\n"); 
          flag = getch();
          fflush(stdin); 
     }  
     return ; 
} 
 
void Show_Data()                                //显示学生信息
{
    Node *p;
    p = head;
    char flag;
    while(p != NULL) 
    { 
        printf("你要查找的学生信息如下:\n"); 
        printf("学号 :%d\n",p -> num);
        printf("名字 :%s\n",p -> name);
        printf("性别 :%s\n",p -> sex);
        printf("年龄 :%d\n",p -> age);
        printf("成绩 :%d\n",p -> sroce); 
        p = p -> next; 
    }
    printf("输出结束,请按任意键继续.\n"); 
    flag = getch();
    fflush(stdin); 
    return ;
}
 
void Delete_Data()                                //按学号删除学生信息
{
     Node *p,*q,*cur; 
     int num;
     char flag = '0'; 
     bool  mark;
     while(flag == '0') 
     { 
          printf("请输入要删除的学生的学号:  "); 
          scanf("%d",&num);  
          fflush(stdin); 
          mark = false;                            //标记是否找到学生
          p = q = head;                               //将头结点head赋值与p 
          if(head == NULL)                       //如果链表中头结点为空,则查询错误 
          {
                printf("删除失败.\n");        
                printf("不存在此学生信息.\n"); 
                return ;
          } 
          else                              //否则开始查询 
          { 
                 while(p != NULL) 
                 { 
                      if(p -> num == num)      //找到学号为num的学生就输出 
                    { 
                        if(head == p)
                            head = p -> next;
                        else
                            q -> next = p -> next; 
                        mark = true;  
                        break; 
                    } 
                      else 
                    {
                        q = p;
                        p = p -> next;
                    }
                } 
          } 
          if(!mark)                                    //没找到学生与num匹配的学生 
          {
               printf("删除失败.\n");        
               printf("不存在学生信息.\n"); 
               return ;
          } 
          printf("删除结束,按 0 键继续,否者退出.\n"); 
          flag = getch();
          fflush(stdin); 
     }  
     return ; 
}
 
void Update_date()                                //修改学生信息    
{
    Node *p; 
     int num;
     char flag = '0'; 
     bool  mark;
     while(flag == '0') 
     { 
          printf("请输入要修改的学生的学号:  "); 
          scanf("%d",&num);  
          fflush(stdin); 
          mark = false;                            //标记是否找到学生
          p = head;                               //将头结点head赋值与p 
          if(head == NULL)                       //如果链表中头结点为空,则查询错误 
          {
                printf("修改失败.\n");        
                printf("不存在此学生信息.\n");
                return ;
          } 
          else                              //否则开始查询 
          { 
                 while(p != NULL) 
                 { 
                      if(p -> num == num)      //找到学号为num的学生就输出 
                    { 
                        printf("请输入姓名:");
                        scanf("%s",&p -> name);
                        printf("请输入学号:");
                        scanf("%d",&p -> num);
                        printf("请输入年龄 :");
                        scanf("%d",&p -> age);
                        printf("请输入性别 :");
                        scanf("%s",&p -> sex);
                        printf("请输入成绩 :");
                        scanf("%d",&p -> sroce);
                          fflush(stdin);                //用来清空输入缓存,以便不影响后面输入的东西
                        mark = true;  
                        break; 
                    } 
                      else 
                        p = p -> next; 
                } 
          } 
          if(!mark)                                    //没找到学生与num匹配的学生 
          {
               printf("修改失败.\n");        
               printf("不存在此学生信息.\n"); 
               return ;
          } 
          printf("修改结束,按 0 键继续,否者退出.\n"); 
          flag = getch();
          fflush(stdin); 
     }  
     return ; 
}
 
void Solve_Data()                                          //将处理后的链表中的信息存进文件
{  
     FILE *fp; 
     fp = fopen("Student","w");                          //以"w"形式打开student文件 
     while(head != NULL)  
     {
            fwrite(head,sizeof(struct Node),1,fp);         //写进student文件 
            head = head -> next; 
     } 
     fclose(fp); 
     return ; 
 } 
 
void List()                                        //菜单选择函数
{
    char x;
    bool flag = true;
    while(flag)
    {
        Interface();                            //菜单函数
        x = getch();
        system( "cls" );
        fflush(stdin);
        switch(x)
        {
            case '1':
                Add_Data();
                break;
            case '2':
                Find_Data();
                break;
            case '3':
                Show_Data();
                break;
            case '4':
                Delete_Data();
                break;
            case '5':
                Update_date();
                break;
            default:
                Solve_Data();
                flag=false;
                break;
        }
    }
    return ;
}
 
int main()
{
    head = Load();
    List();
    return 0;
}

直接控制台运行查看结果,望采纳

在这里插入图片描述


 
// 链表
const LinkList = function() {
    this.head = null;
    this.length = 0;
 
    // 辅助类,创建节点
    const Node = function(element) {
        this.element = element;
        this.next = null; //因为next用来存放对象,null是一个空的对象,因此这里使用空很合适
    };
 
    //在链表末尾添加元素
    this.__proto__.append = function(element) {
        const node = new Node(element);
        if (this.head === null) {
            this.head = node;
        } else {
            // 拿一个变量接收找到的最后一个节点,将添加的元素添加到最后一个节点的next属性
            let current = this.head;
            while (current.next) {
                current = current.next;
            }
            current.next = node;
        }
        this.length++;
    };
 
    // 获取链表的头
    this.__proto__.getHead = function() {
        return this.head;
    };
 
    //得到链表的长度
    this.__proto__.size = function() {
        return this.length;
    };
 
    // 往链表指定位置插入元素(下标位置position从0开始)
    this.__proto__.insert = function(position, element) {
        let node = new Node(element);
        // 插入位置不能越界
        if (position > -1 && position <= this.length) {
            // 在开头插入元素,相当于交换(插入的node和head两个数)
            if (position == 0) {
                let current = this.head;
                this.head = node;
                this.head.next = current;
            } else if (position == this.length) {
                //在末尾的位置插入
                this.append(element);
                // 在append方法中新建了一个node,所以将这个作用域中的node赋值为null,释放内存
                node = null;
                // append方法中执行了this.length++
                this.length--;
            } else {
                // previous插入坐标前一个节点 current当前插入坐标的节点
                let previous = null;
                let current = this.head;
                let index = 0;
                while (index < position) {
                    previous = current;
                    current = current.next;
                    index++;
                }
                previous.next = node;
                node.next = current;
            }
            this.length++;
            return true;
        } else {
            // return new Error("插入的下标位置越界了,不能这样");
            return false;
        }
    };
 
    //检查链表是否为空
    this.__proto__.isEmpty = function() {
        return this.length === 0;
    };
 
    //传入要删除某个位置下标的元素
    this.__proto__.removeAt = function(position) {
        // 越界问题
        if (position > -1 && position < this.length) {
            let current = this.head;
            //删除链表第一个元素
            if (position === 0) {
                this.head = current.next;
            } else {
                //while循环退出条件是,查找到链表的index下标位置为position时,进行删除操作
                let index = 0;
                let previous = null;
                // 查询
                while (index < position) {
                    previous = current;
                    current = current.next;
                    index++;
                }
                // 当index == position时,删除
                previous.next = current.next;
            }
            this.length--;
            return current;
        } else {
            return false;
        }
    };
 
    //获取指定element的下标position
    this.__proto__.indexOf = function(element) {
        let index = 0;
        let current = this.head;
        while (current) {
            if (current.element == element) {
                return index;
            }
            current = current.next;
            index++;
        }
        return -1;
    };
 
    // 删除指定元素
    this.__proto__.remove = function(element) {
        return this.removeAt(this.indexOf(element));
    };
 
    // 更新指定position下标的节点
    this.__proto__.update = function(position, element) {
        if (this.get(position)) {
            this.get(position).element = element;
            return true;
        }
        return false;
    };
 
    // 获取指定position下标的节点
    this.__proto__.get = function(position) {
        // 越界判断
        if (position > -1 && position < this.length) {
            let current = this.head;
            let index = 0;
            while (index < position) {
                current = current.next;
                index++;
            }
            return current;
        } else {
            return false;
        }
    };
 
    // 删除链表最后一个节点
    this.__proto__.delete = function() {
        this.removeAt(this.length - 1);
    };
 
    // 以数组的形式输出链表所有的值
    this.__proto__.toArray = function() {
        return (function reversePrint(head) {
            if (head) {
                if (head.next) {
                    return [...reversePrint(head.next), head.element]
                }
                return [head.element]
            }
            return []
        })(this.head);
    }
};
 
// 快排
Array.prototype.quickSort = function() {
    // 交叉替换辅助函数
    const swap = function(array, index1, index2) {
        let arrCopy = array[index2];
        array[index2] = array[index1];
        array[index1] = arrCopy;
    };
    // 递归辅助函数
    function quickSortRec(array) {
        if (array.length === 1) {
            return array;
        }
        const mid = array[Math.floor(array.length / 2)];
        let leftIndex = 0;
        let rightIndex = array.length - 1;
        while (leftIndex < rightIndex) {
            while (array[leftIndex].score < mid.score && leftIndex < rightIndex) {
                leftIndex++;
            }
            while (array[rightIndex].score > mid.score && leftIndex < rightIndex) {
                rightIndex--;
            }
            swap(array, leftIndex, rightIndex);
            leftIndex++;
            rightIndex--;
        }
        return quickSortRec(array.slice(0, Math.floor(array.length / 2))).concat(
            quickSortRec(array.slice(Math.floor(array.length / 2), array.length))
        );
    }
 
    return quickSortRec(this);
};
 
// 学生类
class Student {
    constructor(name, sex, studentId, score) {
        this.name = name;
        this.sex = sex;
        this.studentId = studentId;
        this.score = score;
    }
}
 
class Main {
    constructor() {
            // 男生组链表
            this.maleLinkList = new LinkList();
            // 女生组链表
            this.femaleLinkList = new LinkList();
        }
        // 录入学生
    entry(student) {
        student.sex === 'male' ? this.maleLinkList.append(student) : this.femaleLinkList.append(student);
    }
 
    result() {
        console.log(this.maleLinkList.toArray().quickSort());
        console.log(this.femaleLinkList.toArray().quickSort());
    }
}
 
const main = new Main();
let i = 0;
while (i < 10) {
    main.entry(new Student(i, i % 2 === 0 ? "male" : "female", i, i));
    i++;
}
main.result();
 
/* 
    输出结果
[
  Student { name: 0, sex: 'male', studentId: 0, score: 0 },
  Student { name: 2, sex: 'male', studentId: 2, score: 2 },
  Student { name: 4, sex: 'male', studentId: 4, score: 4 },
  Student { name: 6, sex: 'male', studentId: 6, score: 6 },
  Student { name: 8, sex: 'male', studentId: 8, score: 8 }
]
[
  Student { name: 1, sex: 'female', studentId: 1, score: 1 },
  Student { name: 3, sex: 'female', studentId: 3, score: 3 },
  Student { name: 5, sex: 'female', studentId: 5, score: 5 },
  Student { name: 7, sex: 'female', studentId: 7, score: 7 },
  Student { name: 9, sex: 'female', studentId: 9, score: 9 }
]
*/

大一写的,改一改应该有用
https://download.csdn.net/download/qq_40331154/10809793?spm=1001.2014.3001.5503