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;
}
实验总结
- 注意临时指针移动不改变原链表
- 注意指针指向的空间改变同步改变原链表
- 注意head的移动和改变
- 注意private下的变量无法在外部引用
- 注意函数是否存在返回值及其类型