一、实验目的
1、熟练掌握线性表的结构特点,掌
握顺序表的基本操作。
2、巩固 C++相关的程序设计方法与技术。
3、学会使用顺序表解决实际问题。
二、实验内容
1、用C++编写完整程序。
2、建立两个双链表链表,一个用以存放学生信息,另一个用来存放学生成绩,利用指针实现双链表链表的基本操作。
3、用类模板构造函数实现相关的操作:输出,插入,删除,查找等功能。
三、源代码
#include<iostream>
#include<string>
using namespace std;
struct Node {
string data;
Node *prior;
Node *next;
};
class Score {
private:
Node *first1;
Node *first2;
public:
Score(string a[], string b[], int n, int m);
~Score();
string Get(string na);
string Locate(int i);
void Insert(string na, string im, int i);
string Delete(string na);
void Printlist();
};
#include<string>
using namespace std;
struct Node {
string data;
Node *prior;
Node *next;
};
class Score {
private:
Node *first1;
Node *first2;
public:
Score(string a[], string b[], int n, int m);
~Score();
string Get(string na);
string Locate(int i);
void Insert(string na, string im, int i);
string Delete(string na);
void Printlist();
};
Score::Score(string a[], string b[], int n, int m) {
first1 = new Node; first2 = new Node;
first1->next = NULL; first2->next = NULL;
for (int i = 0; i < n; i++) {
struct Node *s = new Node;
s->prior = first1->prior;
s->data = a[i];
s->next = first1->next;
first1->next = s;
}
for (int i = 0; i < m; i++) {
struct Node*k = new Node;
k->prior = first2->prior;
k->data = b[i];
k->next = first2->next;
first2->next = k;
}
}
Score::~Score() {
while (first1 != NULL) {
Node*q = first1; Node*t = first2;
first1 = first1->next; delete q;
}
}
first1 = new Node; first2 = new Node;
first1->next = NULL; first2->next = NULL;
for (int i = 0; i < n; i++) {
struct Node *s = new Node;
s->prior = first1->prior;
s->data = a[i];
s->next = first1->next;
first1->next = s;
}
for (int i = 0; i < m; i++) {
struct Node*k = new Node;
k->prior = first2->prior;
k->data = b[i];
k->next = first2->next;
first2->next = k;
}
}
Score::~Score() {
while (first1 != NULL) {
Node*q = first1; Node*t = first2;
first1 = first1->next; delete q;
}
}
void Score::Insert(string na, string im, int i) {
Node*p = first1; Node*s = first2;
int count = 1; int count1 = 1;
if (p == NULL)throw"位置异常";
while (p != NULL&&count <= i) {
Node*p = first1; Node*s = first2;
int count = 1; int count1 = 1;
if (p == NULL)throw"位置异常";
while (p != NULL&&count <= i) {
if (count == i) {
Node*q = new Node;
q->data = na;
q->prior = p;
q->next = p->next;
p->next->prior = q;
p->next = q;
}
p = p->next; count++;
}
Node*q = new Node;
q->data = na;
q->prior = p;
q->next = p->next;
p->next->prior = q;
p->next = q;
}
p = p->next; count++;
}
if (s == NULL)throw"位置异常";
while (s != NULL&&count1 <= i) {
while (s != NULL&&count1 <= i) {
if (count1 == i) {
Node*j = new Node;
j->data = im;
j->prior = s;
j->next = s->next;
s->next->prior = j;
s->next = j;
}
s = s->next; count1++;
}
}
Node*j = new Node;
j->data = im;
j->prior = s;
j->next = s->next;
s->next->prior = j;
s->next = j;
}
s = s->next; count1++;
}
}
string Score::Get(string na) {
Node*p = first1->next; Node*q = first2->next;
while (p != NULL&&q != NULL) {
if (p->data == na) {
return q->next->data;
}
else { p = p->next; q = q->next; }
}
}
Node*p = first1->next; Node*q = first2->next;
while (p != NULL&&q != NULL) {
if (p->data == na) {
return q->next->data;
}
else { p = p->next; q = q->next; }
}
}
string Score::Locate(int i) {
Node*p = first1->next;
int count = 1;
if (p == NULL)throw"位置异常";
while (p != NULL&&count<i) {
p = p->next;
count++;
}
return p->data;
}
Node*p = first1->next;
int count = 1;
if (p == NULL)throw"位置异常";
while (p != NULL&&count<i) {
p = p->next;
count++;
}
return p->data;
}
string Score::Delete(string na) {
Node*p = first1; Node*s = first2;
while (p->data != na) {
p = p->next; s = s->next;
while (p->next->data == na) {
Node*q = p->next; string x = q->data;
p->next = q->next;
delete q;
Node*j = s->next; string y = j->data;
s->next = j->next;
delete j;
return y; return x;
}
}
if (p->next = NULL)throw"位置异常";
Node*p = first1; Node*s = first2;
while (p->data != na) {
p = p->next; s = s->next;
while (p->next->data == na) {
Node*q = p->next; string x = q->data;
p->next = q->next;
delete q;
Node*j = s->next; string y = j->data;
s->next = j->next;
delete j;
return y; return x;
}
}
if (p->next = NULL)throw"位置异常";
}
void Score::Printlist() {
Node*p = first1->next; Node*s = first2->next;
while (p != NULL&&s != NULL) {
cout << "学生姓名为:" << p->data << endl;
p = p->next;
cout << "数据结构成绩为:" << s->data << endl;
s = s->next;
}
}
int main() {
string a[3] = { "kk","cc","woojin" };
string b[3] = { "99","89","87" };
cout << "-------------------------------------------" << endl;
Score K(a, b, 3, 3);
K.Printlist();
cout << "-------------------------------------------" << endl;
cout << "查询kk的成绩:" << K.Get("cc") << endl;
cout << "-------------------------------------------" << endl;
cout << "查询位于第二位置的学生:" << K.Locate(2) << endl;
cout << "-------------------------------------------" << endl;
cout << "输入学生的信息:" << endl;
K.Insert("Daniel", "88", 2);
K.Printlist();
cout << "-------------------------------------------" << endl;
cout << "删除名为cc的学生信息:" << endl;
K.Delete("cc");
K.Printlist();
string a[3] = { "kk","cc","woojin" };
string b[3] = { "99","89","87" };
cout << "-------------------------------------------" << endl;
Score K(a, b, 3, 3);
K.Printlist();
cout << "-------------------------------------------" << endl;
cout << "查询kk的成绩:" << K.Get("cc") << endl;
cout << "-------------------------------------------" << endl;
cout << "查询位于第二位置的学生:" << K.Locate(2) << endl;
cout << "-------------------------------------------" << endl;
cout << "输入学生的信息:" << endl;
K.Insert("Daniel", "88", 2);
K.Printlist();
cout << "-------------------------------------------" << endl;
cout << "删除名为cc的学生信息:" << endl;
K.Delete("cc");
K.Printlist();
}
四、实验结果
五、总结与疑问
双链表与单链表的的不同之处就在于多了个prior指针域存放前边节点的地址,查找前边节点会更方便,但是由于指针域过多容易混淆,涉及多个双链表更是如此,要明确每个语句的意思才能准确敲出代码。
为何在删除函数中,两个双链表的函数操作一摸一样却只有其中一个能删除函数?
循环条件出现差错,在一个if函数中分开两次进行返回,返回第一个数值后边的操作就不进行了,因此我把return函数都放在最后边,函数能正常运行。