title: 2022-5-11链表实验 date: 2022-05-12 15:17:42 tags: Knowledge
链表实验题
文件装配(头文件):linkedList.hpp
typedef int DataType;
class node {
public:
node(DataType d =0 , node* ptr = nullptr) { data = d; next = ptr; }
DataType data;
node* next;
};
class linked_list {
private:
node* head, * tail; //表首、表尾
int size; //有效数据个数
public:
linked_list(); //无参构造,初始化一个空的链表(若定义为带哨兵的链表则默认包含一个结点)
linked_list(const linked_list& other); //拷贝构造
linked_list& operator=(const linked_list& right); //赋值重载
int list_size() const; //求链表数据集中的数据规模
//集合并交叉也可以考虑设计为类外函数
linked_list operator+(const linked_list& right); //链表集合并
linked_list operator-(const linked_list& right);//链表集合差
linked_list intersectionSet(const linked_list& right); //链表集合交
node* find(DataType value); //查找1 返回包含value值的结点地址,找不到返回空指针
bool find(DataType value, node*& pre, node*& p);
//查找2: 找到返回真:p为目标点,pre为前驱点; 找不到返回假:p和pre均为nullptr
void add_front(DataType value); //添加到首
void add_tail(DataType value);//添加到尾
void add_pos_after(DataType value, node* pos); //添加到指定位置之后
void add_pos_before(DataType value, node* pos);//添加到指定位置之前
void Delete(DataType value);//删除指定值
void delete_pos_after(node* pos);//删除指定位置之后
void delete_pos_before(node* pos);//删除指定位置之前
void delete_all(DataType value);//删除所有包含value的结点
void delete_repeat(); //将链表调整为无重复元素的集合
void reverse();//逆置链表
void sort();//升序排列当前链表
void display();//遍历链表,使用逗号间隔输出元素
friend linked_list mergeSortedList(const linked_list& L1, const linked_list& L2);
~linked_list(); //回收链表内的所有结点
};
linked_list mergeSortedList(const linked_list& L1, const linked_list& L2);
文件装配(函数封装文件):linkListfun.cpp
#include <iostream>
using namespace std;
#include <Windows.h>
#include "linkedList.hpp"
//无参构造函数
linked_list::linked_list()
{
head=tail = new node;
size = 0;
}
//拷贝构造函数
linked_list::linked_list(const linked_list& other)
{
size = 0;
head = tail = new node;
head->data = other.head->data;
tail = head;
size++;
node* pt = other.head->next;
while (pt) {
node* Nnode = new node(pt->data);
tail->next = Nnode;
tail = Nnode;
pt=pt->next;
size++;
}
//这个我定义的太天真了,因为涉及到内存的删除,所以一定要建立新空间
//head = other.head;
//tail = other.tail;
//size = other.size;
}
//赋值重载
linked_list& linked_list::operator=(const linked_list& right)
{
head = tail = new node;
head->data = right.head->data;
tail = head;
size++;
node* pt = right.head->next;
while (pt) {
node* Nnode = new node(pt->data);
tail->next = Nnode;
tail = Nnode;
pt = pt->next;
size++;
}
//这个我定义的太天真了,因为涉及到内存的删除,所以一定要建立新空间
//head = tail = new node;
//head = right.head;
//tail = right.tail;
//size = right.size;
return (*this);
}
//求链表的数据规模
int linked_list::list_size() const
{
return size;
}
//遍历链表
void linked_list::display()
{
node* p = head;
int i = 0;
while (p&&i<size)
{
if (i == 0)
cout << p->data;
else cout << ',' << p->data;
i++;
p = p->next;
}
cout << endl;
}
//添加到首
void linked_list::add_front(DataType value)
{
node* Nnode = new node(value);
Nnode->next = head;
head = Nnode;
if (size == 0)
{
tail = head;
tail->next = nullptr;
}
size++;
}
//添加到尾
void linked_list::add_tail(DataType value)
{
node* Nnode = new node(value);
if (size == 0)
{
head = Nnode;
}
tail->next = Nnode;
tail = Nnode;
size++;
}
//查找1 返回包含value值的结点地址,找不到就返回空
node* linked_list:: find(DataType value)
{
node* p = head;
while (p && p->data != value) { p = p->next; };
return p;
}
//查找2 返回是否找到值,通过指针的引用记住地址
bool linked_list::find(DataType value, node*& pre, node*& p)
{
p = head;
for (; p && p->data != value; pre = p, p = p->next);
if (p)
return 1;
else return 0;
}
//到指定位置后添加元素
void linked_list::add_pos_after(DataType value, node* pos)
{
if (pos)
{
node* Nnode = new node(value);
Nnode->next = pos->next;
pos->next = Nnode;
size++;
}
else cout << "-----------------链表中未有此位置----------------" << endl;
}
//到指定元素前添加元素
void linked_list::add_pos_before(DataType value, node* pos)
{
node* p = head;
if (p == pos) {
node* Nnode = new node(value);
Nnode->next = head;
head = Nnode;
size++;
return;
}
while (p && p->next != pos)
{
p = p->next;
}
if (p)
{
if (pos != NULL)
{
node* Nnode = new node(value);
p->next = Nnode;
Nnode->next = pos;
size++;
}
else cout << "-----------------链表中未有此位置----------------" << endl;
}
}
//进行并集操作(注意别去改了原值)
linked_list linked_list::operator+(const linked_list& right)
{
linked_list temp;
node* temp1 = head;
while (temp1) {
temp.add_tail(temp1->data);
temp1 = temp1->next;
}
node* pr = right.head;
while (pr) {
node* pl = temp.head;
for (; pl->data != pr->data && pl->next != NULL; pl = pl->next);
if (pl->next==NULL&&pl->data!=pr->data)
{
//这里会改变原链表需要调用函数才行
temp.add_tail(pr->data);
temp.size++;
pr = pr->next;
}
else
pr = pr->next;
}
return temp;
}
//进行交集操作
linked_list linked_list::intersectionSet(const linked_list& right)
{
linked_list temp;
node* pr = head;
while (pr) {
node* pl =right.head;
for (; pl && pl->data != pr->data; pl = pl->next);
if (pl!=NULL) {
temp.add_tail(pr->data);
pr = pr->next;
}
else {
pr = pr->next;
}
}
return temp;
}
//进行差集操作
linked_list linked_list::operator-(const linked_list& right)
{
linked_list temp;
node* pl = head;
while (pl) {
node* pr = right.head;
for (; pr && pr->data != pl->data; pr = pr->next) ;
if (pr == NULL) {
temp.add_tail(pl->data);
pl = pl->next;
}
else {
pl = pl->next;
}
}
return temp;
}
//删除单个指定值
void linked_list::Delete(DataType value) {
node* p = head;
node* pre = nullptr;
for (; p && p->data != value; pre = p, p = p->next);
if (p) {
if (pre) {
pre->next = p->next;
delete p;
}
else {
head = head->next;
delete p;
}
size--;
}
else {
cout << "------------------------------未找到相关值可删除----------------------" << endl;
}
}
//删除指定位置之后
void linked_list::delete_pos_after(node* pos)
{
if (pos->next) {
node* p = pos->next;
pos->next = p->next;
size--;
delete p;
}
else cout << "----------------------------------该位置之后不存在于链表中------------------------------" << endl;
}
//删除指定位置之前
void linked_list::delete_pos_before(node* pos)
{
node* p, * pre;
pre = nullptr;
p = head;
if (pos == p)
{
cout << "---------------------该位置之前不存在于表中-----------------" << endl;
}
else {
if (p->next == pos) {
head = head->next;
size--;
delete p;
}
else {
for (; p && p->next != pos; pre = p, p = p->next);
if (p)
{
pre->next = pos;
size--;
delete p;
}
else {
cout << "---------------------该位置之前不存在于表中-----------------" << endl;
}
}
}
}
//删除所有包含value的结点
void linked_list::delete_all(DataType value) {
node* p = head;
node* pre = nullptr;
while (p) {
if (p->data == value)
{
if (p==head)
{
node* temp = p;
p = p->next;
head = head->next;
delete temp;
size--;
}
else {
node* temp = p;
pre->next = p->next;
p = p->next;
delete temp;
size--;
}
}
else {
pre = p;
p = p->next;
}
}
}
//将链表调整为无重复元素的集合
void linked_list::delete_repeat() {
node* p = head;
node* pre = nullptr;
while (p) {
node* p1 = head;
while (p1) {
if (p1 == p)
{
pre = p1;
p1 = p1->next;
continue;
}
else {
if (p1->data==p->data) {
if (pre) {
pre->next = p1->next;
node* temp = p1;
p1 = p1->next;
size--;
delete temp;
}
else {
head = head->next;
node* temp = p1;
p1 = p1->next;
delete temp;
size--;
}
}
else {
pre = p1;
p1 = p1->next;
}
}
}
p = p->next;
}
}
//链表逆置
void linked_list::reverse() {
node* p = head ->next;
node* Lhead = head;
Lhead->next = nullptr;
tail = Lhead;
while (p) {
node* Nnode = new node(p->data);
Nnode->next = Lhead;
Lhead = Nnode;
p = p->next;
}
head = Lhead;
}
//升序排列当前列表选择排序
void linked_list::sort()
{
node* p = head;
node* p1;
for (; p->next; p = p->next) {
for (p1 = p->next; p1; p1 = p1->next)
{
if (p->data > p1->data)
{
DataType temp = p -> data;
p->data = p1->data;
p1->data = temp;
}
}
}
}
//有序表的合并
linked_list mergeSortedList(const linked_list& L1,const linked_list& L2) {
linked_list temp;
node* p1 = L1.head; node* p2 = L2.head;
while (p1 && p2) {
if (p1->data < p2->data) {
temp.add_tail(p1->data);
p1 = p1->next;
}
else if (p1->data > p2->data)
{
temp.add_tail(p2->data);
p2 = p2->next;
}
else {
temp.add_tail(p1->data);
p1 = p1->next;
p2 = p2->next;
}
}
while (p1)
{
temp.add_tail(p1->data);
p1 = p1->next;
}
while (p2) {
temp.add_tail(p2->data);
p2 = p2->next;
}
return temp;
}
//析构函数
linked_list::~linked_list()
{
//在用这种删除时一定要注意自己的赋值以及复制函数一定新建立内存去储存,不然会出现内存丢失。
node* temp;
temp = head;
while (head) {
head = head->next;
delete temp;
temp = head;
}
}
按顺序对所写函数的验证:
#include <iostream>
using namespace std;
#include "linkedList.hpp"
int main()
{
linked_list a1, a2;
DataType value;
while (cin >> value)
{
if (value == 0)
break;
a1.add_front(value);
}
a1.display();
while (cin >> value)
{
if (value == 0)
break;
a2.add_tail(value);
}
a2.display();
//类内查找函数的测试
/*cout << "---------------------请输入您要查找的值(查找方式1)----------------" << endl;
cin.clear();
cin >> value;
node* p = a1.find(value);
if (p!=NULL)
{
cout << "--原始值--" << '\t' << value << endl;
cout << "--链表中的值--" << '\t' << p->data << endl;
}
else cout << "--sorry,can't find!--" << endl;
node* pre=nullptr;
node* p1 = nullptr;
cout << "----------------------请输入您要查找的值(查找方式2)------------------" << endl;
cin >> value;
a2.find(value, pre, p1);
if (p1 != NULL)
{
cout << "--原始值--" << '\t' << value << endl;
cout << "--链表中的值--" << '\t' << p1->data << endl;
}
else cout << "--sorry,can't find!--" << endl;*/
//类内指定位置添加值的测试
/*//第一步找建立一个位置(以值中桥梁去找位置,用查找函数1)
cout << "---------------请输入您要查找的位置的值(目的在其后添加值)----------------" << endl;
cin >> value;
node* p = a1.find(value);
cout << "-----------------请输入您要在后添加的值----------------------" << endl;
cin >> value;
a1.add_pos_after(value, p);
a1.display();
cout << endl;
cout << "---------------请输入您要查找的位置的值(目的在其前添加值)----------------" << endl;
cin >> value;
p = a2.find(value);
cout << "-----------------请输入您要在前添加的值----------------------" << endl;
cin >> value;
a2.add_pos_before(value, p);
a2.display();
cout << endl;*/
//并差交集的测试
/*linked_list c;
c = a1+a2;
c.display();
cout << endl;
linked_list d;
d = a1.intersectionSet(a2);
d.display();
cout << endl;
linked_list e;
e = a1 - a2;
e.display();*/
//值的删除测试
/*//单个value值删除测试
cout << "--------------------请输入您要删除的值----------------------" << endl;
cin >> value;
a1.display();
cout << endl;
cout << a1.list_size();
cout << endl;
a1.Delete(value);
a1.display();
cout << endl;
cout << a1.list_size();
cout << "-------请输入要删除位置的值(删除值后的位置)----------------" << endl;
cin >> value;
node* p = a1.find(value);
a1.delete_pos_after(p);
a1.display();
cout << endl;
cout << "-------请输入要删除位置的值(删除值前的位置)----------------" << endl;
cin >> value;
p = a2.find(value);
a2.delete_pos_before(p);
a2.display();
cout << endl;
//删除所有包含value的值
cout << "----------------------请输入要删除的值(表中所有这样的值的位置都删除)---------------" << endl;
cin >> value;
a1.display();
cout<<endl << a1.list_size();
cout << endl;
a1.delete_all(value);
cout << a1.list_size() << endl;
a1.display();*/
//删除链表重复值的测试
/*cout << a1.list_size() << endl;
a1.display();
cout << endl;
a1.delete_repeat();
cout << a1.list_size()<<endl;
a1.display();*/
//逆置链表测试
/*cout << endl << endl << endl;
a2.display();
cout << endl;
a2.reverse();
a2.display();*/
//链表升序测试
/*a1.display();
cout << endl;
a1.sort();
a1.display();
cout << endl;*/
return 0;
}
文件装配(测试程序)Demo.cpp
//测试程序:
#include<iostream>
using namespace std;
#include "linkedList.hpp"
int main()
{
linked_list a1, a2, b, c; //若设计的类为模板,则采用linked_list<int> a1,a2,b,c;
DataType data; //若设计为模板类,这此处直接使用int data;
//正向和逆向建链测试
//输入2 ,6, 7, 3, 5, 9,12, 4 ,0
while (cin >> data) {
if (data == 0) break; //输入0结束
a1.add_front(data);
a2.add_tail(data);
}
a1.display(); //逆向链 4,12,9,5,3,7,6,2
a2.display(); //正向链2,6,7,3,5,9,12,4
//链表转置测试
//输入2 ,16, 3, 8, 15, 4, 9, 7 ,0
while (cin >> data) {
if (data == 0) break; //输入0结束
b.add_tail(data);
}
b.display(); //原始链表2,16,3,8,15,4,9,7
b.reverse();
b.display(); //转置结果7,9,4,15,8,3,16,2
c = a1 + b; //测试集合并
c.display(); //4,12,9,5,3,7,6,2,15,8,16
c = a1 - b; //测试集合差(属于a1且不属于b的数据)
c.display(); //12,5,6
c = a1.intersectionSet(b); //测试集合交
c.display(); //4,9,3,7,2
a1.sort(); //测试升序排序
a1.display(); //2,3,4,5,6,7,9,12
//思考需要降序排序如何做?
b.add_tail(8);
b.add_tail(16);
b.add_tail(3);
b.add_front(3);
b.add_front(16);
b.display(); //16,3,7,9,4,15,8,3,16,2,8,16,3
b.delete_all(16); //删除所有的16
b.display();//3,7,9,4,15,8,3,2,8,3
b.delete_repeat(); //将b调整为无重复集合
b.display();//3,7,9,4,15,8,2
node* pos = b.find(15);
b.add_pos_after(18, pos);
b.display(); //3,7,9,4,15,18,8,2
b.add_pos_before(23, pos);
b.display();//3,7,9,4,23,15,18,8,2
b.delete_pos_after(pos);
b.display();//3,7,9,4,23,15,8,2
b.delete_pos_before(pos);
b.display();//3,7,9,4,15,8,2
b.Delete(7);
b.display();//3,9,4,15,8,2
b.Delete(8);
b.display();//3,9,4,15,2
b.sort();
b.display();//2,3,4,9,15
a2 = mergeSortedList(a1, b);
a2.display(); //2,3,4,5,6,7,9,12,15
return 0;
}
结果:
2 6 7 3 5 9 12 4 0 4,12,9,5,3,7,6,2 2,6,7,3,5,9,12,4 2 16 3 8 15 4 9 7 0 2,16,3,8,15,4,9,7 7,9,4,15,8,3,16,2 4,12,9,5,3,7,6,2,15,8,16 12,5,6 4,9,3,7,2 2,3,4,5,6,7,9,12 16,3,7,9,4,15,8,3,16,2,8,16,3 3,7,9,4,15,8,3,2,8,3 3,7,9,4,15,8,2 3,7,9,4,15,18,8,2 3,7,9,4,23,15,18,8,2 3,7,9,4,23,15,8,2 3,7,9,4,15,8,2 3,9,4,15,8,2 3,9,4,15,2 2,3,4,9,15 2,3,4,5,6,7,9,12,15
本文档详细介绍了链表操作实验,包括链表的创建、节点操作(如添加、删除、查找)、集合运算(并、交、差)以及排序、逆置等高级功能的实现。通过实例展示了如何使用`linkedList.hpp`和`linkListfun.cpp`中的函数进行链表管理。
2320





