数据结构单链表

《数据结构》实验报告     
程序名:                                               
一、上机实验的问题和要求:
设计一个程序来实现集合(元素类型为int)的运算,交集、并集二个运算选择一个完成即可,请在自己完成的运算后面打勾:
交集
并集✔
1.生成两个存有集合的单链表,按照元素值递增。
2.通过调用单链表的成员函数来实现集合的运算。每个运算用一个普通函数实现。

二、程序设计的基本思想,原理和算法描述:
(包括程序的结构,数据结构,输入/输出设计,符号名说明等)
使用上次的单链表进行修改,修改插入操作,有序。
先设计一个排序函数将链表进行排序。
再设计一个函数将链表进行合并。
接着设计一个函数将链表中含有相同的元素进行删除。
最后在外面添加一个普通函数Union实现两个集合的并集操作。
Main函数提示用户输入两个集合,输出返回结果。


















三、源程序及注释(说明每个文件的文件名即可,电子档的*.h和*.cpp文件压缩传到FTP上):

#pragma once
#pragma once

template<class DataType>
struct Node
{
	DataType data;
	Node<DataType>* next;
};
template<class DataType>
class LinkList
{
public:
	LinkList();
	LinkList(DataType a[], int n);
	~LinkList();
	int Locate(DataType x);
	void Insert(int i, DataType x);
	DataType Delete(int i);
	void PrintList();
	
    //排序链表
	Node* sortList(Node* head);
	private:
	Node<DataType>* first;
	
};
//合并两个排序的列表
	Node<DataType>* mergeTowLists(Node* l1, Node* l2);
	//从排序的链表中删除所有重复的元素,以便每一个元素只出现一次
	Node<Datatype>* deleteDuplicates(Node* head);
#include<iostream>
using namespace std;
#include "LinkList.h"

template<class DataType>
LinkList<DataType>::LinkList()
{
	first = new Node<DataType>;
	first->next = NULL;
}
template<class DataType>
LinkList <DataType>::LinkList(DataType a[], int n)
{
	Node<DataType>* r, * s;
	first = new Node<DataType>;
	r = first;
	for (int i = 0; i < n; i++)
	{
		s = new Node<DataType>;
		s->data = a[i];
		r->next = s;
		r = s;

	}
	r->next = NULL;
}
template <class DataType>
LinkList<DataType> ::~LinkList()
{
	Node<DataType>* q = NULL;
	while (first != NULL)
	{
		q = first;
		first = first->next;
		delete q;
	}
}
template<class DataType>
void LinkList<DataType>::Insert(int i, DataType x)
{
	Node<DataType>* p = first, * s = NULL;
	int count = 0;
	while (p != NULL && count < i - 1)
	{
		p = p->next;
		count++;
	}
	if (p == NULL) throw"位置";
	else {
		s = new Node<DataType>;
		s->data = x;
		s->next = p->next;
		p->next = s;
	}
}
template<class DataType>
DataType LinkList<DataType>::Delete(int i)
{
	Node<DataType>* p = first, * q = NULL;
	DataType x;
	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;
	}

}
template <class DataType>
int LinkList<DataType>::Locate(DataType x)
{
	Node<DataType>* p = first->next;
	int count = 1;
	while (p != NULL)
	{
		if (p->data == x)
			return count;
		p = p->next;
		count++;
	}
	return 0;
}
template<class DataType>
void LinkList<DataType>::PrintList()
{
	//cout << "PrintList start:" << endl;
	Node<DataType>* p = first->next;
	while (p != NULL)
	{
		//cout << "PrintList while:" << endl;
		cout << p->data << "  ";
		p = p->next;
	}
	cout << endl;
}


//合并两个排序的列表 template<class DataType>
Node*mergeTowLists(Node* l1, Node* l2)
{

	Node<DataType>* head = new Node<DataType>(-1);
	Node<DataType>* p = head;
	while (l1 != NULL || l12 != NULL)
	{
		int val1 = l1 == NULL ? INT_MAX : l1->val;
		int val2 = l2 == NULL ? INT_MAX : l2->VaL;
		if (val1 <= val2)
		{
			p->next = l1;
			l1 = l1->next;
		}
		else
		{
			p->next = l2;
			l2 = l2->next;
		}
		p = p->next;
	}
	p = head->next;
	delete head;
	return p;
}
//从排序的链表中删除重复的元素1
//删除所有重复的元素,以便每一个元素只出现一次
template<class DataType>

Node* deleteDuplicates(Node* head)
{
	if (head == NULL)return NULL;
	Node<DataTrype>* pre = head;
	Node<DataType>* p = head->next;
	while (p != NULL)
	{
		if (pre->val == p->val)
		{
			ListNode* temp = p;
			p = p->next;
			pre->next = p;
			delete temp;
			coutinue;
		}
		pre = pre->next;

	}
	return head;
}

//排序链表
template<class DataType>

Node* LinkList<DataType>::sortList(Node* head)
{
	//首先得到长度length
	Node<DataTppe>* p = head;
	int len = 0;
	while (p != NULL)
	{
		p = p->next;
		len++;
	}
	Node<DataType>* fakehead = new Node<DataType>(-1);
	fakehead->next = head;
	for (int interval = 1;interval <= len;interval * 2)
	{
		Node*<DataType> pre = fakehead;
		Node* <DataType>slow = fakehead->next,
			* <DataType>fast = fakehead->next;
		while (fast != NULL || slow != NULL)
		{
			int i = 0;
			while (i < interval && fast != NULL)
			{
				fast = fast->next;
				i++;
			}
			int fvisit = 0, svisit = 0;
			while (fvisit < interval && svisit < interval && fast != NULL && slow != NULL)
			{
				if (fast->val < slow->val)
				{
					pre->next = fast;
					pre = fast;
					fast = fast->next;
					fvisit++;
				}
				else
				{
					pre->next = slow;
					pre = slow;
					slow = slow->next;
					svisit++;
				}

			}
			while (fvisit < interval && fast != NULL)
			{
				pre->next = fast;
				pre = fast;
				fast = fast->next;
				fvisit++;

			}
			while (svisit < interval && slow != NULL)
			{
				pre->next = slow;
				pre = slow;
				slow = slow->next;
				svisit++;
			}
			pre->next = fast;
			slow = fast;

		}
	}
	Node* newhead = fakehead->next;
	delete fakehead;
	return newhead;
}
#include "LinkList.h"
#include "LinkList.cpp"

int main()

{   
int a[6] = {1,3,2,4,6,5};
int b[3] = {2,7,4};
    LinkList<int>A(a,5);
	LinkList<int>B(b, 3);
	LinkList<int>C;
	cout << "原来A数组为:" << endl;
	A.PrintList();
	cout << "原来B数组为:" << endl;
	B.PrintList();
	A.sortList<int>(&A);//排序链表A
	B.sortList<int>(&B);//排序链表B
	C=mergeTowLists<int>(&A, &B);//合并链表A,B
    C.deleteDuplicates<int>(&C)//删除合并后链表中一样的数值
	cout << "A,B的并集为:" << endl;
	C.PrintList();
}

四、运行输出结果:
(可以将运行结果抓图贴至此处)









五、调试和运行程序过程中产生的问题及采取的措施:
一开始的写出函数其实是很简短的,尤其是排序函数。但后来在我在《编程谜题》这本书看到了链表排序函数发现这上面写的大概是我的两倍,进行对比发现确实是我考虑的条件不够全面,导致给的数据有的时候能实现,有的时候实现不了。这一现象更加证实了我们一开始学习代码所学的一句话,没有办法证明函数是正确的,只能找出bug证明是错误的。






六、对算法的程序的讨论、分析,改进设想,其它经验教训:
一开始的算法十分简单,步骤也很粗略,就写了两步先把集合A中的元素放入集合C再找出B中与A不同的元素按顺序插入进去。但是在实行的过程中实现起来较为困难,比如插在哪里怎么拆进去之类的。于是拆分成了几个更小的函数,虽然步骤好像变多了,要写的函数也多了,但是这样思路会更加清晰。也更容易把问题找出来。





七、对数据结构教学的意见和建议:

  • 0
    点赞
  • 0
    收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

wsswsswss123

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值