一.实验目的
巩固双链表的数据结构的存储方法和相关操作,学会针对具体应用,使用线性表的相关知识来解决具体问题。
二. 实验内容
建立一个由n个学生成绩的顺序表,n的大小由自己确定,每一个学生的成绩信息由自己确定,实现数据的对表进行插入、删除、查找等操作。用双链表链表来实现,分别输出结果。
为了以后的对代码的修改、优化和复用,这里采用了C++中的模板来实现,下面是模板的实现。
DoubleLinkList.h
#ifndef DoubleLinkList_h
#define DoubleLinkList_h
#include<iostream>
using namespace std;
template<class DataType>
struct Node
{
DataType data;
Node<DataType> *next;
Node<DataType> *prior;
};
template<class DataType>
class DoubleLinkList
{
private:
Node<DataType> *head;
Node<DataType> *tail;
int length;
public:
// 构造函数
DoubleLinkList(int length);
// 正向遍历
void traverseList();
// 反向遍历
void traverseListReturn();
// 排序列表
void sortList();
// 插入操作
bool insert(int index, DataType x);
// 修改链表中指定位置的节点
bool ChangeList(int postion, int num);
// 删除特定位置
DataType DeleteList(int postion);
// 按位查找
DataType GetList(int postion);
// 析构函数
~DoubleLinkList() {};
};
#endif /* DoubleLinkList_h */
DoubleLinkList.cpp
#include "DoubleLinkList.h"
template<class DataType>
DoubleLinkList<DataType>::DoubleLinkList(int length)
{
this -> length = length;
head = new Node<DataType>;
head -> prior = NULL;
tail = head;
for (int i = 0; i < length; i++)
{
Node<DataType> *temp = new Node<DataType>;
cout << "Please enter the no." << i + 1 << ":Node's data:";
cin >> temp -> data;
temp -> next = NULL;
temp -> prior = tail;
tail -> next = temp;
tail = temp;
}
}
template<class DataType>
void DoubleLinkList<DataType>::traverseList()
{
Node<DataType> *p = head -> next;
while (p != NULL)
{
cout << p -> data << " ";
p = p -> next;
}
cout << endl;
}
template<class DataType>
void DoubleLinkList<DataType>::traverseListReturn()
{
Node<DataType> *p = tail;
while (p -> prior != NULL)
{
cout << p -> data << " ";
p = p -> prior;
}
cout << endl;
}
template<class DataType>
void DoubleLinkList<DataType>::sortList()
{
Node<DataType> *p = new Node<DataType>;
Node<DataType> *q = new Node<DataType>;
DataType temp;
for (p = head -> next; p -> next != NULL; p = p -> next)
{
for (q = p -> next; q != NULL; q = q -> next)
{
if (q -> data < p -> data)
{
temp = q -> data;
q -> data = p -> data;
p -> data = temp;
}
}
}
}
template<class DataType>
bool DoubleLinkList<DataType>::insert(int index, DataType x)
{
if (index < 1 || index > length)
{
return false;
}
Node<DataType> *p = new Node<DataType>;
p -> data = x;
Node<DataType> *q = head;
for (int i = 0; i < index; i++)
{
q = q -> next;
}
p -> prior = q -> prior;
q -> prior -> next = p;
p -> next = q;
q -> prior = p;
length++;
return true;
}
template<class DataType>
bool DoubleLinkList<DataType>::ChangeList(int postion, int num)
{
Node<DataType> *p = head -> next;
if (postion > length || postion < 1)
{
return false;
}
for (int i = 0; i < postion - 1; i++)
{
p = p -> next;
}
p -> data = num;
return true;
}
template<class DataType>
DataType DoubleLinkList<DataType>::DeleteList(int postion)
{
Node<DataType> *p = head -> next;
if (postion > length || postion < 1)
{
return -1;
}
for (int i = 0; i < postion - 1; i++)
{
p = p -> next;
}
p -> prior -> next = p -> next;
p -> next -> prior = p -> prior;
Node<DataType> *d = p;
delete p;
length--;
return d -> data;
}
template<class DataType>
DataType DoubleLinkList<DataType>::GetList(int postion)
{
Node<DataType> *p = head -> next;
if (postion > length || postion < 1)
{
return -1;
}
for (int i = 0; i < postion - 1; i++)
{
p = p -> next;
}
return p -> data;
}
以上模板实现了双链表的基本结构,可以实现对数据的插入、删除、查找等基本功能。下面是用模板的应用~
main.cpp
#include <iostream>
#include "DoubleLinkList.cpp"
using namespace std;
int main(int argc, const char * argv[]) {
DoubleLinkList<float> list(5);
cout << "正向遍历成绩表" << endl;
list.traverseList();
cout << "反向遍历成绩表" << endl;
list.traverseListReturn();
cout << "在4号位置插入分数 95" << endl;
list.insert(4, 95);
cout << "正向遍历成绩表" << endl;
list.traverseList();
cout << "排序分数表" << endl;
list.sortList();
cout << "正向遍历成绩表" << endl;
list.traverseList();
cout << "反向遍历成绩表" << endl;
list.traverseListReturn();
cout << "将第3个位置的分数改为 100" << endl;
list.ChangeList(3, 100);
cout << "正向遍历成绩表" << endl;
list.traverseList();
cout << "读取第五个位置的分数为:";
cout << list.GetList(5) << endl;
cout << "删除第三个位置的分数" << endl;
list.DeleteList(3);
cout << "正向遍历成绩表" << endl;
list.traverseList();
return 0;
}
运行结果如下:
三. 总结和心得
上面的代码实现了实验所要求的对学生成绩表的基本操作功能,也使用了双链表来实现。在程序设计时双链表比单链表写起来难度增加了,也复杂了一点。
双链表中很多功能和之前的写的单链表的功能差不多,写起来并没有什么困难。双链表比单链表复杂是它用了两个指针,一个指向前一个人,另一个指向后一个,使它可以正向反向遍历。在操作指针的时候,也需要注意它的操作顺序。我在写那时不时都会有点乱,需要再巩固一下。最近都在写swift的demo,在swift中程序员不需要去考虑’*’号的问题。在习惯了objective-c和swift的语法后,敲回C++还是一时有点转不过来,需要多加练习。