【数据结构与算法】【C++】单链表实验报告

目录

阅读建议:

一、实验目的

二、实验内容

三、实验过程

四、代码结构

五、测试结果


阅读建议:

1.实验的软硬件环境要求:

(1)硬件环境要求:PC机
(2)软件环境要求:Windows 环境下的 Microsoft Visual Studio

2.该实验采用了头文件(.h)和源文件(.cpp)相结合的形式。


一、实验目的

1. 熟练掌握单链表的存储特点;

2. 熟练掌握单链表的基本操作算法;

3. 熟练掌握面向对象程序设计方法;

4. 能灵活使用单链表解决具体的问题。


二、实验内容

1.在主函数中定义对象,并调用成员函数,验证单链表的基本操作;

2.定义单链表类模板,例如LinkList,封装单链表的操作算法,包括:

        a.创建

        b.释放

        c.按值查找

        d.按序号查找

        e.第i个位置插入和删除元素

        f.求链表长度

        g.输出单链表所有元素

        h.原地置逆单链表

        i.判断单链表是否递增

        j.删除有序单链表中的值相同的多余结点(只保留一个值)

3.在主函数中定义对象,并调用成员函数,验证单链表的基本操作。


三、实验过程

1.构造结点

using namespace std;
template 
struct Node
{
	T data;  //数据域
	Node* next;  //指针域
};

2.单链表初始化---无参构造函数

template
LinkList::LinkList()
{
	first = new Node;
	first->next = NULL;
}

3.建立单链表---带参构造函数

template
LinkList::LinkList(T a[], int n)
{
	//头插法
	//first = new Node;
	//first->next = NULL;  //初始化空链表
	//for (int i = 0; i < n; i++) {
	//	Node* s = NULL;
	//	s = new Node;
	//	s->data = a[i];
	//	s->next = first->next;
	//	first->next = s;
	//}

	//尾插法
	first = new Node;
	Node* r = first, * s = NULL;  //尾指针初始化
	for (int i = 0; i < n; i++) {
		s = new Node;
		s->data = a[i];
		r->next = s;
		r = s;
	}
	r->next = NULL;
}

4.判空,若单链表为空返回 0 ,否则返回 1。

template
int LinkList::Empty()
{
	if (first->next == NULL) {
		return 0;
	}
	else{
		return 1;
	}
}

5.长度,设置计数器,循环遍历单链表,返回链表长度。

template
int LinkList::Length()
{
	Node* p = first->next;  //工作指针初始化
	int count = 0;  //累加器 count 初始化
	while (p!=NULL){
		count++;
		p = p->next;
	}
	return count;
}

6.遍历,设置工作指针,循环遍历单链表,逐一输出每个结点元素。

template
void LinkList::PrintList()
{
	Node* p = first->next;  //工作指针初始化
	while (p != NULL) {
		cout << p->data<<" ";
		p = p->next;
	}
}

7.按位查找,设置工作指针和计数器,根据传入的参数 i 循环遍历,当计数器数值等于 i 时,返回工作指针所指结点的元素。

template
T LinkList::Get(int i)
{
	Node* p = first->next;  //工作指针初始化
	int count = 1;  //累加器 count 初始化
	while (p!=NULL && countnext;
		count ++ ;
	}
	if (p == NULL) {
		throw "查找位置错误!";
	}else {
		return p->data;
	}
}

8.按值查找,设置工作指针和计数器,根据传入的参数 x 循环遍历,当工作指针所指结点的元素值等于 x 时,返回计数器的值。

template
int LinkList::Locate(T x)
{
	Node* p = first->next;  //工作指针初始化
	int count = 1;  //累加器 count 初始化
	while (p!=NULL){
		if (x == p->data) {
			return count;
		}
		p = p->next;
		count++;
	}
	throw "查找失败!";
}

9.插入操作,设置工作指针和计数器,根据传入的参数 i 和 x ,循环遍历 i 次,然后将 x 插入此位置。

template
void LinkList::Insert(int i, T x)
{
	Node* p = first, * s = NULL;  //工作指针初始化
	int count = 0;  //累加器 count 初始化
	while (p!=NULL && countnext;
		count++;
	}
	if (p == NULL) {
		throw "插入位置错误!";
	}
	else
	{
		s = new Node;
		s->data = x;
		s->next = p->next;
		p->next = s;
	}
}

10.按位删除,设置工作指针和计数器,根据传入的参数 i  ,循环遍历 i 次,然后将此处所指的元素删除。

template
T LinkList::Delete(int i)
{
	T x;
	Node* p = first, * q = NULL;
	int count = 0;
	while (p != NULL && count < i - 1)
	{
		p = p->next;
		count++;
	}
	if (p == NULL || p->next == NULL) {
		throw "删除位置错误!";
	}else {
		q = p->next;
		x = q->data;
		p->next = q->next;
		delete(q);
		return x;
	}
}

11.置逆,设置工作指针,在循环过程中不断将结点倒接。

template
void LinkList::Reverse()
{
	Node* p = first->next,* t = NULL,* q = NULL;

	while (p != NULL)
	{
		q = p->next;
		p->next = t;
		t = p;
		p = q;
	}
	first->next = t;
}

12.判断是否递增,设置工作指针,循环遍历单链表比较前后两个结点所指元素的大小,若有前者比后者大的情况则返回 false ,否则返回 true 。

template
bool LinkList::isIncreasing() 
{
	Node* p = first->next;
	if (p == NULL) {
		return true; // 链表为空,认为是递增的  
	}
	Node* q = p->next;
	while (q != NULL) {
		if (p->data > q->data) {
			return false;
		}
		p = q;
		q = p->next;
	}
	return true;
}

13.删除重复,设置工作指针,建立双层循环,逐一比较每个结点所指元素。

template
void LinkList::removeDuplicates() 
{
	Node* p = first,* q,*s;
	while (p != nullptr) {
		s = p;
		q = p->next;
		while (q != nullptr) {
			if (p->data == q->data) {
				// 删除重复节点  
				s->next = q->next;
				delete q;  // 释放内存  
				q = s->next;
			}else {
				s = q;
				q = q->next;
			}
		}
		p = p->next;
	}
}

14.销毁,设置工作指针,循环遍历整个单链表,然后逐一删除每个结点。

template
LinkList::~LinkList()
{
	Node* p = first;  //工作指针初始化
	while (first != NULL) {
		first = first->next;
		delete p;
		p = first;
	}
}

15.主函数

int main() 
{
	int r[6] = { 1,5,7,8,5,5 },i,x;
	//创建
	LinkList L{r, 6};

	//输出单链表所有元素
	cout << "初始单链表元素为:";
	L.PrintList();
	cout << endl;

	//删除有序单链表中的值相同的多余结点(只保留一个值)
	cout << "删除重复元素后:";
	L.removeDuplicates();
	L.PrintList();

	//判空
	cout <> i;
		if (i <= L.Length()) {
			cout << "元素:" << L.Get(i) << endl;
			break;
		}else {
			cout << "请重新输入:";
		}
	}

	cout << "请输入需要查找序号的元素:";
	while (1) {
		cin >> x;
		int count = 0;
		for (int i=0; i < L.Length(); i++) {
			if (x == r[i]) {
				count++;
				cout << "序号:" << L.Locate(x) << endl;
				break;
			}
		}
		if (count != 0) {
			break;
		}
		cout << "请重新输入:";
	}

	//第i个位置插入元素
	cout << "请输入需要插入的序号:";
	cin >> i;
	cout << "请输入需要插入的元素:";
	cin >> x;
	cout << "插入数据后单链表为:";
	L.Insert(i, x);
	L.PrintList();

	//第i个位置删除元素
	cout << endl <<"请输入需要删除的序号:";
	cin >> i;
	cout << "删除的元素为:" << L.Delete(i) << endl;
	cout << "删除数据后单链表为:";
	L.PrintList();

	//判断单链表是否递增
	cout << endl << "是否递增:";
	if (L.isIncreasing() == false) {
		cout << "否";
	}else if(L.isIncreasing() == true){
		cout << "是";
	}

	//原地置逆单链表
	cout << endl << "原地置逆后:";
	L.Reverse();
	L.PrintList();

	//判断单链表是否递增
	cout << endl << "是否递增:";
	if (L.isIncreasing() == false) {
		cout << "否";
	}
	else if (L.isIncreasing() == true) {
		cout << "是";
	}

	//释放
	L.~LinkList();
	cout << endl << "【已释放单链表存储空间】";
	
	return 0;

}

四、代码结构

【数据结构与算法】【C++】单链表实验报告_第1张图片


五、测试结果

【数据结构与算法】【C++】单链表实验报告_第2张图片


        完整代码链接:https://download.csdn.net/download/weixin_73286497/88758650

        希望大家可以在该篇实验报告中有所收获,同时也感谢各位大佬的支持。文章如有任何问题请在评论区留言斧正,鸿蒙会尽快回复您的建议!

你可能感兴趣的:(数据结构,#,C++,c++,开发语言,数据结构,算法,链表)