面向对象程序设计-实验三 链表

2022/4/11
1.课堂练习:节点类Node,包含整形数data;链表类LinkList,包含头指针Head,完成构造函数和析构函数,实现功能包括:向链表头插入一个整形数push,遍历链表并显示display,查找特定的整形数findData,按照从小到大的顺序插入一个整形数insertData,删除整形数deleteData。编写主函数,测试每个成员函数的输出,运行结果截图。
#include<iostream>
using namespace std;
class node{
public:
	int data;
	node* next;
};//定义节点
node* createList(int n) {
	node* temp, * tail = nullptr, * head = nullptr;
	int num;
	cin >> num;
	head = new node;//为新节点动态分配内存
	if (head == nullptr) {
		cout << "No memory available ! ";
		return nullptr;
	}
	else {
		head->data = num;
		head->next = nullptr;
		tail = head;
	}
	for (int i = 0; i < n - 1; i++) {
		cin >> num;
		temp = new node;// 为新节点动态分配内存
		if (temp == nullptr) {
			cout << "No memory available ! ";
			return head;
		}
		else {
			temp->data = num;
			temp->next = nullptr;
			tail->next = temp;
			tail = temp;
		}
	}
	return head;
}
class Linklist {
public:
	Linklist(int n) {
		head = createList(n);
	}//构造函数
	~Linklist(){
		node* temp = head;
		node* x;
		while (temp) {
			x = temp->next;
			delete temp;
			temp = x;
		}
	}//析构函数
	void display();//显示数据
	void add(int push);//插入开头
	void find(int findData);//寻找数据
	void insert(int insertData);//插入数据
	void deletee(int deleteData);//删除数据
private:
	node* head;
};
void Linklist::display() {
	cout << "List: ";
	node* temp = head; 
	while (temp) {
		cout << temp->data;
		if (temp->next) {
			cout << " -> ";
		}
		temp = temp->next;
	}
	cout << endl;
}
void Linklist::add(int push) {
	node *temp = head;
	head = new node;
	head->data = push;
	head->next = temp;
}
void Linklist::find(int findData) {
	node* temp = head;
	int i;
	while (temp) {
		if (temp->data == findData) {
			cout << "Find "<< findData << " in the list." << endl;
			break;
		}
		temp = temp->next;
	}
	if (temp == nullptr) {
		cout << "Can't find " << findData << " in the list." << endl;
	}
}
void Linklist::insert(int insertData) {
	node* temp = head;
	node* x = new node;
	x->data = insertData;
	while (temp) {
		if (temp->data <= x->data) {
			if (temp->data) {
				x->next = temp->next;
			}
			else {
				x->next = nullptr;
			}
			temp->next = x;
			break;
		}
		temp = temp->next;
	}
}
void Linklist::deletee(int deleteData) {
	node* temp = head;
	if (temp->data == deleteData) {
		head = head->next;
	}
	else {
		while (temp) {
			if (temp->next->data == deleteData) {
				temp->next = temp->next->next;
				break;
			}
			temp = temp->next;
		}
	}
}
int main(){
	int n;
	cout << "P1ease enter the number of nodes : ";
	cin >> n;
	Linklist list(n);
	list.add(1);//在开头插入1
	list.display();//显示数据
	list.find(2);//寻找数据2
	list.insert(4);//插入数据4
	list.deletee(3);//删除数据3
	list.display();//显示数据
	return 0;
}
2. Josephus(约瑟夫)问题:有n个人围成一个圈,从第1个人开始报数,数到第m个人,让他出局;然后从出局的下一个人重新开始报数,数到第m个人,再让他出局,……,如此反复直到剩下一个人,问此人编号为几?

利用链表解决约瑟夫问题。编写主函数,运行结果截图。

#include<iostream>
#include<string>
using namespace std;
class node {
public:
	int data;
	node* next;
};//定义节点
class Linklist {
public:
	Linklist() {
		head = new node;
		head->next = nullptr;
	}//构造函数
	void Josephus();
private:
	node* head;
};
void Linklist::Josephus() {
	int n, m;
	cout << "请输入总人数以及出局的数:" << endl;
	cin >> n >> m;
	node* temp = head;
	for (int i = 1; i <= n; i++){
		node* x = new node;
		x->data = i;
		temp->next = x;
		temp = x;
	}
	temp->next = head;
	node* c1 = head;
	int num = 0;
	while (n > 1){
		if (num + 1 == m){
			node* c2 = c1->next->next;
			c1->next = c2;
			c1->next->data = c2->data;
			c1 = c1->next;
			num = 0;//报数清零
			n = n - 1;//人数减一
		}//轮到序号出局
		else {
			c1 = c1->next;
		}
		num = num + 1;//报到的数
	}
	cout << "最后的编号为:" << c1->data << endl;
}
int main() {
	Linklist J;
	J.Josephus();
	return 0;
}
3.输入n以及n个学生的信息(姓名,成绩)(n>=10),再删除其中成绩小于60分的节点,然后将学生按照成绩升序排列。插入一位学生的信息,然后顺序输出这些学生的信息,要求用链表结构完成,并将各操作编写成成员函数。编写主函数,测试每个成员函数的输出,运行结果截图。
#include<iostream>
#include<string>
using namespace std;
class node {
public:
	string name;
	int score;
	node* next;
};//定义节点
node* student(int n) {
	node* temp;
	node* tail = nullptr;
	node* head = nullptr;
	string name;
	int score;
	cout << "请输入学生姓名:";
	cin >> name;
	cout << "请输入学生成绩:";
	cin >> score;
	head = new node;//为新节点动态分配内存
	if (head == nullptr) {
		cout << "No memory available ! ";
		return nullptr;
	}
	else {
		head->name = name;
		head->score = score;
		head->next = nullptr;
		tail = head;
	}
	for (int i = 0; i < n - 1; i++) {
		cout << "请输入学生姓名:";
		cin >> name;
		cout << "请输入学生成绩:";
		cin >> score;
		temp = new node;// 为新节点动态分配内存
		if (temp == nullptr) {
			cout << "No memory available ! ";
			return head;
		}
		else {
			temp->name = name;
			temp->score = score;
			temp->next = nullptr;
			tail->next = temp;
			tail = temp;
		}
	}
	return head;
}
class Linklist {
public:
	Linklist(int n) {
		head = student(n);
		num = n;
	}//构造函数
	void deletee();//删除数据
	node* sor(node* head);//从小到大排序返回指针
	void sortt();//修改链表内指针
	void insert();//插入数据
	void display();//显示数据
private:
	node* head;
	int num;//学生人数
};
void Linklist::deletee() {
	node* temp = head;
	while (temp->score < 60) {
		head = head->next;
		temp = head;
		num = num - 1;
	}//判断开头
	while (temp && temp->next) {
		if (temp->next->score < 60) {
			temp->next = temp->next->next;
			num = num - 1;
		}
		temp = temp->next;
	}
}
node* Linklist::sor(node* head) {
	if (!head || !head->next) {
		return head;
	}//空指针或一个数据
	node* fast = head->next;//快指针
	node* slow = head;//慢指针
	while (fast != nullptr && fast->next != nullptr) {
		fast = fast->next->next;
		slow = slow->next;
	}
	node* ss = slow->next;
	slow->next = nullptr;
	node* left = sor(head);//左递归
	node* right = sor(ss);//右递归
	node* ans = new node;//新链表
	node* temp = ans;
	while (left != nullptr && right != nullptr) {
		if (left->score > right->score) {
			temp->next = right;
			right = right->next;
		}
		else {
			temp->next = left;
			left = left->next;
		}
		temp = temp->next;
	}
	if (left == nullptr) {
		temp->next = right;
	}
	else {
		temp->next = left;
	}
	return ans->next;
}
void Linklist::sortt() {
	head = sor(head);
}
void Linklist::insert() {
	string name;
	int score;
	cout << "请输入插入的学生姓名:";
	cin >> name;
	cout << "请输入插入的学生成绩:";
	cin >> score;
	node* temp = head;
	node* x = new node;
	x->name = name;
	x->score = score;
	while (temp) {
		if (temp->score <= x->score) {
			if (temp->score) {
				x->next = temp->next;
			}
			else {
				x->next = nullptr;
			}
			temp->next = x;
			break;
		}
		temp = temp->next;
	}
}
void Linklist::display() {
	node* temp = head;
	while (temp) {
		cout << temp->name << " " << temp->score << endl;
		temp = temp->next;
	}
}
int main() {
	int n;
	cout << "请输入学生人数: ";
	cin >> n;
	Linklist Stu(n);
	Stu.deletee();//删除小于60分的节点
	Stu.sortt();//从小到大排序
	Stu.insert();//插入数据
	Stu.display();//显示数据
	return 0;
}
实验总结
  1. 注意临时指针移动不改变原链表
  2. 注意指针指向的空间改变同步改变原链表
  3. 注意head的移动和改变
  4. 注意private下的变量无法在外部引用
  5. 注意函数是否存在返回值及其类型
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闻闻闻闻笛声

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值