1.为什么当要删除最后一个元素时,会引发异常
2.为什么无法查找学生信息
3.查找前驱后继元素函数部分的代码哪里有问题
#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;
}
}
1、循环逻辑可以这样:找到学号为a的元素,删除,否则继续。这样删除:
lnode p = current;
current->pre->next = current->next;
if (current->next) {
current->next->pre=current->pre
}
delete p;
2、查找逻辑:从传入的 l 开始,l->stu.num == a 返回 l->stu。否则循环直到 l 为null输出该学生不存在。
3、findbeforeAndAfter 里面的参数 p, q 要传引用。