可以帮忙看看eraselnode()函数和searchlnode()函数吗,删除函数每次遇到学号不在里面的就崩,搜索函数一直呈现没有该学生,是哪里逻辑出问题了呐
#include<iostream>
#include<string>
using namespace std;
typedef struct { //结构体定义
int num;
char name[10];
}student;
typedef struct Lnode {
student stu;
Lnode* pre;
Lnode* next;
}*lnode;
bool initlnode(lnode& l) {//链表初始化
l = new Lnode;
if (l == nullptr) { cout << "链表初始化失败" << endl; return false; }
else {
l->next = NULL;
return true;
}
}
bool creatlnode(lnode& l, const int a) { //链表赋值
lnode current = l;
cout << "请输入链表信息" << endl;
for (int i = 1; i <= a; i++) {
lnode temp = new Lnode;
cout << "请输入第" << i << "个学生的数据" << endl;
cin >> temp->stu.num;
cin >> temp->stu.name;
current->next = temp;
temp->next = nullptr;
temp->pre = current;
current = temp;
}
return true;
}
bool insert(lnode& l, const student a, const int b) {//插入到b后
if (l->next == nullptr) return false;
lnode temp = new Lnode;
temp->stu = a;
lnode current = l->next;
int i = 0;
for (i = 0; i < b - 1 && current != nullptr; i++) {
current = current->next;//current指向b
}
if (i < b - 1 || current == nullptr) return false;
if (current->next) {
current->next->pre = temp;
temp->next = current->next;
temp->pre = current;
}
else {
temp->next = nullptr;
temp->pre = current;
}
if (!current) {
cout << "插入失败" << endl;
return false;
}
current->next = temp;
return true;
}
bool eraselnode(lnode& l, const int a) {//删除学号为a的元素
if (!l->next || a < 1) { return false; }
lnode current = new Lnode;
current = l->next;
while (current->stu.num != a && current != nullptr) {
current = current->next;
}
if (current == nullptr) {
return false;
}
else {
if (current->next) {
lnode p = current;
current->pre->next = current->next;
current->next->pre = current->pre;
delete p;
return true;
}
else {
lnode p = current;
current->pre->next = current->next;
delete p;
return true;
}
}
}
bool searchlnode(lnode& l, const int a, student& b) {//查找学号为a的元素
if (l->next == nullptr) {
cout << "空链表,无法查找" << endl;
return false;
}
lnode current = l->next;
while(l->stu.num != a && current != nullptr) {
current = current->next;
}
if (!current) {
cout << "该学生不存在" << endl;
return false;
}
b = current->stu;
return true;
}
bool findbeforeAndAfter(lnode& l, const int i, lnode &m, const int j, lnode &n, int &num) {//查找第i个前驱,第j个后继
if (l->next == nullptr) {
return false;
}
lnode current = l->next;
while (current->stu.num != num && current->next != nullptr) {
current = current->next;
}
if (current->stu.num != num && current == nullptr) {
return false;
}
lnode temp = current;
for (int t = i; t > 0; t--) {
temp = temp->pre;
if (temp->pre == nullptr) {
m = nullptr;
cout << "前驱查找失败,请检查您输入的数值是否在正确范围内" << endl;
return false;
}
}
m = temp;
lnode temp2 = current;
for (int t = j; t > 0; t--) {
temp2 = temp2->next;
if (temp2 == nullptr) {
n = nullptr;
cout << "后继查找失败,请检查您输入的数值是否在正确范围内" << endl;
return false;
}
}
n = temp2;
return true;
}
void print(lnode& l) {
if (!l->next) { cout << "链表为空!" << endl; }
lnode current = new Lnode;
current = l->next;
while (current) {
cout << current->stu.num << " " << current->stu.name << endl;
current = current->next;
}
}
int main() {
lnode stulist;
while (1) {
if (initlnode(stulist)) {
cout << " 请输入学生个数" << endl;
int stnum;
cin >> stnum;
creatlnode(stulist, stnum);
}
else cout << "链表初始化错误,请检查程序" << endl;
choose:cout << "请选择您要实现的功能:" << endl;
cout << "1.插入学生信息 2.删除学生信息 3.查找学生信息 4.查找前驱后继" << endl;
int a;
cin >> a;
switch (a) {
case 1:
student stinsert;
cout << "请输入插入学生的学号" << endl;
cin >> stinsert.num;
cout << "请输入插入学生的姓名" << endl;
cin >> stinsert.name;
cout << "请输入要插入的位置(将在你输入的元素位置之后插入)" << endl;
int locinsert;
cin >> locinsert;
if (insert(stulist, stinsert, locinsert)) {
cout << "插入成功" << endl;
print(stulist);
}
else cout << "插入失败" << endl;
goto choose;
case 2:
cout << "请输入你要删除学生的学号" << endl;
int locerase;
cin >> locerase;
if (eraselnode(stulist, locerase)) {
cout << "删除成功" << endl;
print(stulist);
}
else { cout << "删除失败" << endl; }
goto choose;
case 3:
cout << "请输入你要查找学生的学号" << endl;
student searchout;
int numsearch;
cin >> numsearch;
if (searchlnode(stulist, numsearch, searchout)) {
cout << "查找成功,您查找的学生信息为:" << endl;
cout << searchout.num << " " << searchout.name << endl;
}
goto choose;
case 4:
cout << "请输入学生学号" << endl;
int flagstu;
cin >> flagstu;
cout << "请输入您向前查找的数目" << endl;
int i;
cin >> i;
cout << "请输入您向后查找的数目" << endl;
int j;
cin >> j;
lnode p = nullptr, q = nullptr;
if (findbeforeAndAfter(stulist, i, p, j, q, flagstu)) {
if (p == nullptr) { cout << "前驱元素查找失败" << endl; }
else {
cout << "前驱元素查找成功" << endl;
cout << "第" << i << "个前驱为:" << endl;
cout << p->stu.num << " " << p->stu.name;
}
if (q == nullptr) { cout << "后继元素查找失败" << endl; }
else {
cout << "第" << j << "个后继为:" << endl;
cout << q->stu.num << " " << q->stu.name;
}
break;
}
else { cout << "错误" << endl; }
goto choose;
}
return 0;
}
}
eraselnode函数中,lnode current= new Lnode;这里不需要new。while循环中,current != nullptr 应该放在前面,否则当current是nullptr时,current->stu.num会导致程序崩溃。
searchlnode函数中while中 current != nullptr应该放在前面,条件中也不应该是 l->stu.num != a ,应该是 current->stu.num != a
两个函数修改如下(修改的地方有注释):
bool eraselnode(lnode& l, const int a) {//删除学号为a的元素
if (!l->next || a < 1) { return false; }
lnode current;// = new Lnode; //修改1,这里不需要new
current = l->next;
while (current != nullptr && current->stu.num != a ) { //修改2, current != nullptr放在前面
current = current->next;
}
if (current == nullptr) {
return false;
}
else {
if (current->next) {
lnode p = current;
current->pre->next = current->next;
current->next->pre = current->pre;
delete p;
return true;
}
else {
lnode p = current;
current->pre->next = current->next;
delete p;
return true;
}
}
}
bool searchlnode(lnode& l, const int a, student& b) {//查找学号为a的元素
if (l->next == nullptr) {
cout << "空链表,无法查找" << endl;
return false;
}
lnode current = l->next;
while (current != nullptr && current->stu.num != a ) { //修改
current = current->next;
}
if (!current) {
cout << "该学生不存在" << endl;
return false;
}
b = current->stu;
return true;
}
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!