数据结构实验一(2):单链表 C++实现

这篇博客详细介绍了如何使用C++定义一个包含学生信息(学号,姓名,成绩)的单链表,并实现了前插法、后插法构建表、遍历、查找、取值、插入、删除和统计学生个数等基本操作。通过友好的菜单式界面,用户可以方便地进行各种操作。
摘要由CSDN通过智能技术生成

数据结构实验一(2):单链表


  1. 实验内容

    定义一个包含学生信息(学号,姓名,成绩)的单链表,使其具有如下功能(参见教材中基本操作):
    (1) 前插法或者后插法构建表;
    (2) 逐个显示学生表中所有学生的相关信息(显示表,即遍历表);
    (3) 根据姓名进行查找,返回此学生的学号和成绩(查找);
    (4) 根据指定的位置可返回相应的学生信息(学号,姓名,成绩)(取值 ); 
    (5) 给定一个学生信息,插入到表中指定的位置(插入); 
    (6) 删除指定位置的学生记录(删除);
    (7) 统计表中学生个数(相当于求表长)。
    
    (1) 定义Student类,表示学生(注:注意=、==、<<、>>的重写);
    (2) 定义LinkList类,表示单链表,每一功能用一成员函数实现,函数名和参数与教材P33基本操作保持一致;
    (3)在主函数中创建LinkList对象,并对各个功能进行测试。
    (4) 程序要做到界面友好(菜单式界面),在程序运行时用户可以根据相应的提示信息进行操作。
    
  2. 单链表功能

    能正常实现各项功能,但不能保证健壮性,

    学生类:

    class Student {
    	string name;
    	int number;
    	int score;
    public:
    	string getName() {
    		return this->name;
    	}
    	Student(string _name = " ", int _number = 0, int _score = 0) {
    		this->name = _name;
    		this->number = _number;
    		this->score = _score;
    	}
    	//运算符重载
    	friend ostream& operator<<(ostream& out, const Student& s) {
    		out <<"姓名:"<< s.name << " 学号:" << s.number << " 成绩:" << s.score;
    		return out;
    	}
    	friend istream& operator>>(istream& in, Student& s) {
    		cin >> s.name >> s.number >> s.score;
    		return in;
    	}
    };
    

    链表结点类:

    //链表结点类
    class LNode {
    public:
    	Student data;//数据域
    	LNode* next;
    	LNode() {
    		this->next = NULL;
    	}
    };
    

    链表类:

    class LinkList {
    	LNode* LHead;//声明一个头指针
    public:
    	LinkList();
    	~LinkList();
    	//尾插法
    	void headInsert(string name,int number,int score);
    
    	//头插法按照位序插入
    	void headInsert(int n,Student s);
    
    	//遍历链表输出
    	void traverseList();
    
    	//删除指定位置结点
    	void deleteList(int i);
    
    	//根据姓名按值查找
    	Student locateList(string name);
    
    	//按序号查找
    	Student getList(int i);
    	//获取链表长度
    	int getLenght();
    	
    };
    

    链表初始化:

    LinkList::LinkList() {
    	this->LHead = new LNode;
    	LHead->next = NULL;  //初始化为空链表
    	if (this->LHead == NULL) {
    		cout << "分配内存失败";
    		return;
    	}
    }
    

    尾插法建立链表:

    //尾插法建立链表
    void LinkList::headInsert(string name, int number, int score) {
    	LNode* p = LHead;
    	while (p->next)
    		p = p->next;
    	LNode* q = new LNode;
    	q->data = Student(name, number, score);
    	p->next = q;
    }
    

    在指定位置使用头插法:

    //在指定位置插入
    void LinkList::headInsert(int n, Student e) {
    	if (n < 1 || n>getLenght()) {
    		cout << "插入位置错误!";
    	}
    	LNode* p;  //p指向当前扫描的点
    	int j = 0;  //p指向第几个
    	p = LHead;  //p指向头结点
    	while (p != NULL && j < n - 1) {
    		p = p->next;
    		j++;
    	}
    	if (p == NULL)
    		cout << "error";
    	LNode* s = new LNode;
    	s->data = e;
    	s->next = p->next;
    	p->next = s;
    	cout << "头插法按位置插入成功" << endl;
    }
    

    根据姓名查询:

    /根据姓名查询
    Student LinkList::locateList(string name) {
    	LNode* p = LHead->next;
    	for (int i = 0; i < getLenght(); i++) {
    		if (p && p->data.getName() != name)
    			p = p->next;
    	}
    	return p->data;
    }
    

    遍历链表:

    void LinkList::traverseList() {
    	LNode* p = LHead;
    	p = p->next;
    	if (LHead == NULL || LHead->next == NULL)
    		cout << "链表不存在或者为空!" << endl;
    	while (p)
    	{
    		cout << p->data << endl;
    		p = p->next;
    	}
    }
    

    获取长度:

    int LinkList::getLenght() {
    	int count = 0;
    	LNode* p = LHead->next;
    	while (p!=NULL)
    	{
    		count++;
    		p = p->next;
    	}
    	return count;
    }
    

    删除指定位置元素:

    void LinkList::deleteList(int i) {
    	LNode* p = LHead;
    	int j = 0;
    	if (i<0 || i>getLenght()) {
    		cout << "请输入正确的删除位置1-" << getLenght() << endl;
    	}
    	if (!(p->next))
    		cout << "链表为空" << endl;
    	while (p->next && j < i - 1) {
    		p = p->next;
    		j++;
    	}
    	LNode* q = new LNode;
    	q = p->next;
    	p->next = q->next;
    	delete q;
    	cout << "删除成功" << endl;
    }
    

    根据指定位置获取数据:

    Student LinkList::getList(int n) {
    	int j = 1;
    	LNode* p = LHead->next;
    	if (n == 0)
    		return LHead->data;
    	if (n < 1)
    		cout << "输入非法";
    	while (p && j < n) {
    		p = p->next;
    		j++;
    	}
    	return p -> data;
    }
    

    析构函数:

    LinkList::~LinkList() {
    	delete LHead;
    }
    
  3. 运行

    void show();
    int main() {
    	LinkList L;
    	show();
    	bool flag = true;
    	while (flag) {
    		int i;
    		cout << "请输入相关数字进行操作:" << endl;
    		cin >> i;
    		switch (i)
    		{
    		case 0:
    			flag = false;
    			break;
    		case 1: {
    			string name; int number; int score;
    			cout << "请依次输入姓名、学号、成绩:" << endl;
    			cin >> name >> number >> score;
    			L.headInsert(name, number, score);
    			break;
    		}
    		case 2:
    			L.traverseList();
    			break;
    		case 3:
    			int i;
    			cout << "请输入要删除的位置" << endl;
    			cin >> i;
    			L.deleteList(i);
    			break;
    		case 4:
    			int j;
    			cout << "请输入要查询的位置,1-" << L.getLenght() << ": ";
    			cin >> j;
    			cout<<L.getList(j)<<endl;
    			break;
    		case 5: {
    			string name;
    			cout << "请输入要查找的姓名: ";
    			cin >> name;
    			cout << L.locateList(name) << endl;
    			break;
    		}
    		case 6:
    			cout<<"链表长度为:"<<L.getLenght()<<endl;
    			break;
    		case 7: {
    			int i;
    			Student e;
    			cout << "请输入要插入的位置:";
    			cin >> i;
    			cout << "请输入姓名、学号、成绩:" << endl;
    			cin >> e;
    			L.headInsert(i, e);
    			break;
    		}
    		default:
    			cout << "输入错误!";
    			break;
    		}
    	}
    	cout << "退出程序";
    	return 0;
    }
    
    void show() {
    	cout << "输入以下数字进行相关操作:\n 1:插入数据\n 2:输出链表信息\n 3.删除指定位置信息\n 4:查找指定位置信息\n 5:输入姓名查找元素信息\n 6.获取元素个数\n 7.指定位置插入\n 0退出\n ";
    }
    
  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值