c++学生链表的实现

链表的实现

实验要求

例6-17的节点结构(学生)和基本流程,用函数分别实现链表的创建、输出、插入、删除和修改节点数据,并在main函数中测试这些函数。基本结构可以参考ppt。

分析

image-20220102205533820

流程

在主函数中,提示用户输入节点个数n,然后提示用户输入指令,并进行相应操作

代码

/**
 * 例6-17的节点结构(学生)和基本流程,用函数分别实现链表的创建、输出、插入、删除和修改节点数据,
并在main函数中测试这些函数。基本结构可以参考ppt。

一律根据学号进行增删改
*/

#include <bits/stdc++.h>
using namespace std;

//学生节点
struct ListNode
{
    long num;
    string name;
    float grade;
    ListNode* next;
    ListNode():num(0),name(""),grade(0),next(nullptr){}
    ListNode(long num_,string name_,float grade_):num(num_),name(name_),grade(grade_),next(nullptr){}
};


//创建,创建有n个结点的链表
ListNode* create(int n){
    ListNode* dummy = new ListNode;
    ListNode* cur = dummy;

    for(int i=0;i<n;i++){
        ListNode* node = new ListNode;
        cout<<"请输入学号,姓名,成绩:\n";
        cin>>node->num>>node->name>>node->grade;
        node->next = nullptr;
        
        cur->next = node;
        cur = cur->next;
	}
    std::cout << "创建成功!\n" << std::endl;
    return dummy->next;
}


//输出
void printList(ListNode* head){
    
    ListNode* cur  = head;

    while(cur != nullptr){
        cout<<cur->num<<" "<<cur->name<<" "<< cur->grade<<endl;
        cur = cur->next;
    }
    std::cout << "打印成功!" << std::endl;
}

//插入
//插入到学号为id的学生后面
void insert(ListNode* head,long id){
    ListNode* cur = head;
    ListNode* newNode = new ListNode;
    newNode->next = nullptr;
    cout<<"请输入要插入的学生的学号,姓名,成绩:\n";
    cin>>newNode->num>>newNode->name>>newNode->grade;

    while(cur->next != nullptr){ //cur将停留在最后一个结点 如果目标节点不存在,则插入在最后,如目标节点存在,也是插入在最后
        if(cur->num == id){ //找到了目标节点,进行插入
            ListNode* temp = cur->next;
            cur->next = newNode;
            newNode->next = temp;
            cout<<"插入成功!\n";
            return;
        }
        cur = cur->next;
    }
    cur->next = newNode;
    newNode->next = nullptr; 
    cout<<"没有找到该学号学生,默认已插入链表尾部!\n";
}

//删除,默认假设删除的id存在
void deleteNode(ListNode* head,long id){
    ListNode* dummy = new ListNode;
    dummy->next = head;
    ListNode* cur = dummy;

    while(dummy != nullptr){
        if(dummy->next->num == id){
            ListNode* temp = dummy->next;
            dummy->next = dummy->next->next;
            delete temp;
            cout<<"删除成功!\n";
            return;
        }
        dummy = dummy->next;
    }
    cout<<"找不到要删除的结点!\n";
}

//修改
//根据id进行修改
void alter(ListNode* head, long id){
    ListNode* cur = head;

    while(cur != nullptr){
        if(cur->num == id){
            cout<<"请输入新的分数:\n";
            cin>>cur->grade;
            break;
        }
        cur = cur->next;
    }
    cout<<"修改成功!\n";
}


//释放链表
void freelist(ListNode* head){
    ListNode* cur = head;

    while(cur != nullptr){
        ListNode* temp = cur->next;
        delete cur;
        cur = temp;
    }
}

//基于命令行的学生链表
int main(){
    int n;
    cout<<"请输入创建的链表的结点个数:\n";
    cin>>n;
    ListNode* head = create(n);
    while(true){
        std::cout << "请输入命令来进行操作:1:打印链表 2:插入 3:删除 4.修改 5.退出\n";
		int op;
        cin>>op;
        
        switch (op) {
			case 1:
				printList(head);
				break;
			case 2:
				std::cout << "请输入学生学号(将插入到该学生后):" << std::endl;
	            long id;
	            cin>>id;
	            insert(head,id);
				break;
			case 3:
				std::cout << "请输入要删除的学生学号:" << std::endl;
//            	long id;
            	cin>>id;
            	deleteNode(head,id);
				break;				
			case 4:
	            std::cout << "请输入要修改的学生的学号:" << std::endl;
//	            long id;
	            cin>>id;
	            alter(head,id);
	            break;
			case 5: 
	            freelist(head);
				std::cout << "已经成功退出!" << std::endl;
				return 0;
			default:
				std::cout << "输入的命令有误,请重新输入!" << std::endl;
				break;
		}
    }

    return 0;
}

实验结果

创建
image-20220102205902233
插入

插入的学号存在时,插入到该学生之后。

image-20220102205929147

插入的学号不存在时候,插入到链表最后。

image-20220102210035471
删除
image-20220102210111716
修改
退出
image-20220102210753342
输入错误的命令
image-20220102210739125

遇到的问题

Bug:

1.在创建链表的函数中,一开始dummy = nullptr导致输入第一个学生后程序就崩溃

解决:应该改为dummy = new ListNode

2.打印链表格式输出有误,姓名和成绩之间少了空格

3.在打印完链表后程序崩溃了

原因:是因为在创建链表的过程中,新建链表后next没有指向空

解决:以后应当在结构体中写构造函数,使得next默认指向null

4.在插入成功之后死循环

可能的原因:提示语句后面加了换行符\n,又加了换行符号endl,系统把endl读入当成了换行符

但改了之后仍然有这个问题

最终解决:输入新节点的时候,写成了cin>>node->num>>node->grade>>node->grade;

应该是:cin>>node->num>>node->name>>node->grade;

总结

1.写代码之前先设计好,再写,能提高效率。

2.写代码时候注意细节,好多bug都是代码细节导致的,后面找bug花了不少时间。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值