山东大学数据结构实验四

链表实现

链表合并

A 链表实现

要求

  1. 封装链表类,链表迭代器类
  2. 链表类需提供操作:在指定位置插入元素,删除指定元素,搜索链表中是否有指定元素,原地逆置链表,输出链表
  3. 不得使用与链表实现相关的STL

描述

第一行两个整数 N 和 Q。
第二行 N 个整数,作为节点的元素值,创建链表。
接下来 Q 行,执行各个操作,具体格式如下:

  • 插入操作 : 1 idx val,在链表的 idx 位置插入元素 val;
  • 删除操作 : 2 val,删除链表中的 val 元素。若链表中存在多个该元素,仅删除第一个。若该元素不存在,输出 -1
  • 逆置操作 : 3,原地逆置链表;
  • 查询操作 : 4 val,查询链表中的 val 元素,并输出其索引。若链表中存在多个该元素,仅输出第一个的索引。若不存在该元素,输出 -1
  • 输出操作 : 5,使用 链表迭代器 ,输出当前链表索引与元素的异或和: f ( chain ) = ∑ i = 0 n − 1 i ⊕ chain [ i ] , n = len(chain) f(\text{chain}) = \sum_{i=0}^{n-1}i\oplus \text{chain}[i], n=\text{len(chain)} f(chain)=i=0n1ichain[i],n=len(chain)

样例 1

Input

10 10
6863 35084 11427 53377 34937 14116 5000 49692 70281 73704 
4 6863
1 2 44199
5
4 21466
1 6 11483
5
4 34937
5
4 6863
1 10 18635

Output

0
398665
-1
410141
5
410141
0

限制

1s

数据范围

image.png
/* created by LYZ */
#include<iostream>
using namespace std;
const int N = 1e6 + 10;
int a[N];//用来存储输入的每个元素
int c[N];//用来存储输出的每个元素 
int stand;
template <class T>
struct chainNode {//定义链表中的结点
	//数据成员
	T element;
	chainNode<T> *next;
	//方法
	chainNode(){}
	chainNode(const T& element)
	{
		this->element = element;
	}
	chainNode(const T& element, chainNode<T>* next)
	{
		this->element = element;
		this->next = next;
	}
};
template<class T>
class Iterator
{
public:
	//C++的向前迭代器所需要的typedef 语句省略
	//构造函数
	Iterator(chainNode<T>* theNode = NULL)
	{
		node = theNode;
	}
	//解引用操作符
	T& operator*() const { return node->element; }
	T* operator->() const { return &node->element; }
	//迭代器加法操作
	Iterator & operator++() //前++
	{
		node = node->next; return *this;
	}
	Iterator operator++(int) //后++
	{
		Iterator old = *this; node = node->next; return old;
	}
	bool operator!=(const Iterator right) const
	{
		return node != right.node;
	}
	bool operator==(const Iterator right) const
	{
		return node == right.node;
	}
protected:
	chainNode<T>* node;//指向表节点的指针
};//迭代器类

template <class T>
class chain
{
public:
	//构造函数、复制构造函数、析构函数
	chain(int initialCapacity = 10);
	chainNode<T>* get1(){
		return firstNode;
	}
	//ADT方法
	bool empty() const { return listSize == 0; }
	int size() const { return listSize; }
	int indexOf(const T& theElement) const;
	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	void reverse();
	int sum();
	Iterator<T> begin(){ return Iterator<T>(firstNode); }
	Iterator<T> end(){ return Iterator<T>(NULL); }
protected:
	chainNode <T> *firstNode;
	//指向链表中第一个节点的指针
	int listSize; //线性表的元素个数

};

template<class T>
chain<T>::chain(int initialCapacity)
{ //构造函数

	firstNode = NULL;
	listSize = 0;
}
template<class T>

int  chain<T>::sum(){
	int res = 0;
	
	chainNode<T>* currentNode= firstNode;
	for (int i = 0; i < listSize;i++){
		res += i^currentNode->element;
		currentNode=currentNode->next;
	}
	return res;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{ //返回元素theElement首次出现时的索引,如果theElement不存在,则返回-1
	//查找元素
	chainNode<T> *currentNode = firstNode;
	int index = 0; // currentNode的索引
	while (currentNode != NULL &&
		currentNode->element != theElement)
	{
		currentNode = currentNode->next;
		index++;
	}
	if (currentNode == NULL) return -1;
	return index;
}//获取链表中某元素的索引
template<class T>
void chain<T>::erase(int theIndex)
{
	//索引有效,需要找要删除的元素节点
	chainNode<T> *deleteNode = firstNode;
	if (theIndex == 0)
	{//删除表中首节点
		deleteNode = firstNode;
		firstNode = firstNode->next;
	}
	else { //用指针p指向第theIndex-1个节点
		chainNode<T> *p = firstNode;
		for (int i = 0; i<theIndex - 1; i++)
			p = p->next;
		deleteNode = p->next;
		p->next = p->next->next;//删除deleteNode指向的节点
	} listSize--;
	delete deleteNode;
}//删除链表中索引值的节点
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{

	//在链表表头插入
	if (theIndex ==0) firstNode = new chainNode<T>(theElement, firstNode);
	else
	{//寻找新元素的前驱(第theIndex-1个元素 )
		chainNode<T> *p = firstNode;
		for (int i = 0; i < theIndex - 1; i++)
			p = p->next; //将p移动至第theIndex-1个元素
		//在p之后插入
		p->next = new chainNode<T>(theElement, p->next);
	}
	listSize++;
}//在链表中插入一个数
template<class T>
void  chain<T>::reverse(){
	if (listSize <= 1)return;
	chainNode<T>* pre = NULL;
	chainNode<T>*next = NULL;
	chainNode<T>*head = firstNode;
	while (head!= NULL)
	{
		next = head->next;
		head->next = pre;
		pre = head;
		head = next;
	}
	firstNode = pre;
}//逆置链表

int main(){
	int n, q;
	cin >> n >> q;
	chain<int> b(n+10);
	chainNode<int>* currentNode = b.get1();
	for (int i = 0; i < n; i++)
	{
		cin >> a[i];
	}
	for (int i = 0; i < n; i++)
	{
	b.insert(i,a[i]); 
	}
	int flag = 0;
	for (int i = 0; i < q; i++)
	{
		cin >> flag;
		switch (flag)
		{
		case 1:
		{int index1 = 0; int val1 = 0;
		cin >> index1 >> val1;
		b.insert(index1, val1);
		break; }
		case 2:
		{int val2;
		cin >> val2;
		int index2 = b.indexOf(val2);
		if(index2!=-1)
		b.erase(index2);
		else {c[stand]=-1;
		stand++;
		}
		break; }
		case 3:
		{b.reverse();
		break; }
		case 4:
		{int val4 = 0;
		cin >> val4;
		int index4 = b.indexOf(val4);
	c[stand]=index4;
	stand ++;
		break; }
		case 5:
		{	int res = b.sum();
		c[stand]=res;
		stand ++;
		break;

		}
		}
	}

for(int i=0;i<stand;i++)
cout<<c[i]<<endl;
	
	return 0;
}

链表合并

要求

  1. 使用题目 链表实现 中实现的链表类、迭代器类完成本题
  2. 不得使用与题目实现相关的STL

描述

给定两组整数序列,你需要分别创建两个有序链表,使用链表迭代器实现链表的合并,并分别输出这三个有序链表的索引与元素的异或和。

Note: 给定序列是无序的,你需要首先得到一个有序的链表

格式

输入

第一行两个整数 N 和 M。
第二行 N 个整数,代表第一组整数序列。
第三行 M 个整数,代表第二组整数序列。

输出

三行整数。分别代表第一组数、第二组数对应的有序链表与合并后有序链表的索引与元素的异或和。

链表异或和的计算方式如下:

$$
f(\text{chain})=\sum_{i=0}^{n-1} i\oplus \text{chain}[i], n=\text{len(chain)}

$$

样例 1

输入

3 0
3 1 2

输出

5
0
5

限制

1s

数据范围

image.png
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6 + 10;
int a[N];//用来存储输入的每个元素
int c[N];
int S, K, Q;
int stand;
int d[N];
int e[N];
int f[N];
int g[N];
void quick_sort(int q[],int l,int r){
    if(l>=r) return ;
    int x=q[l+r>>1], i=l-1, j=r+1;
    while(i<j){
        do i++;while(q[i]<x);
        do j--;while(q[j]>x);
        if(i<j)swap(q[i],q[j]);
        
    }
    quick_sort(q,l,j);
    quick_sort(q,j+1,r);
}


template <class T>
struct chainNode {//定义链表中的结点
	//数据成员
	T element;
	chainNode<T> *next;
	//方法
	chainNode(){}
	chainNode(const T& element)
	{
		this->element = element;
	}
	chainNode(const T& element, chainNode<T>* next)
	{
		this->element = element;
		this->next = next;
	}
};
template<class T>
class Iterator
{
public:
	//C++的向前迭代器所需要的typedef 语句省略
	//构造函数
	Iterator(chainNode<T>* theNode = NULL)
	{
		node = theNode;
	}
	//解引用操作符
	T& operator*() { return node->element; }
	T* operator->() { return &node->element; }
	//迭代器加法操作
	Iterator & operator++() //前++
	{
		node = node->next; return *this;
	}
	Iterator operator++(int) //后++
	{
		Iterator old = *this; node = node->next; return old;
	}
	bool operator!=(const Iterator right) const
	{
		return node != right.node;
	}
	bool operator==(const Iterator right) const
	{
		return node == right.node;
	}
protected:
	chainNode<T>* node;//指向表节点的指针
};//迭代器类

template <class T>
class chain
{
public:
	//构造函数、复制构造函数、析构函数
	chain(int initialCapacity = 10);
	chainNode<T>* get1(){
		return firstNode;
	}
	//ADT方法
	bool empty() const { return listSize == 0; }
	int size() const { return listSize; }
	int indexOf(const T& theElement) const;
	void erase(int theIndex);
	void insert(int theIndex, const T& theElement);
	void reverse();
	int sum();
	Iterator<T> begin(){ return Iterator<T>(firstNode); }
	Iterator<T> end(){ return Iterator<T>(NULL); }
	int * transpose();
protected:
	chainNode <T> *firstNode;
	//指向链表中第一个节点的指针
	int listSize; //线性表的元素个数

};
template<class T>

int * chain<T>::transpose()

{
	int *a = new int[listSize];
	chainNode<T>*currentNode = firstNode;
	for (int i = 0; i < listSize; i++)
	{
		a[i] = currentNode->element;
		currentNode = currentNode->next;
	}
	return a;

}
int yihuoSum(int a[], int n){
	quick_sort(a,0,n-1);
	int res = 0;
	for (int i = 0; i < n; i++)
		res += a[i] ^ i;
	return res;

}


template<class T>
chain<T>::chain(int initialCapacity)
{ //构造函数

	firstNode = NULL;
	listSize = 0;
}
template<class T>

int  chain<T>::sum(){
	int res = 0;

	chainNode<T>* currentNode = firstNode;
	for (int i = 0; i < listSize; i++){
		res += i^currentNode->element;
		currentNode = currentNode->next;
	}
	return res;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const
{ //返回元素theElement首次出现时的索引,如果theElement不存在,则返回-1
	//查找元素
	chainNode<T> *currentNode = firstNode;
	int index = 0; // currentNode的索引
	while (currentNode != NULL &&
		currentNode->element != theElement)
	{
		currentNode = currentNode->next;
		index++;
	}
	if (currentNode == NULL) return -1;
	return index;
}//获取链表中某元素的索引
template<class T>
void chain<T>::erase(int theIndex)
{
	//索引有效,需要找要删除的元素节点
	chainNode<T> *deleteNode = firstNode;
	if (theIndex == 0)
	{//删除表中首节点
		deleteNode = firstNode;
		firstNode = firstNode->next;
	}
	else { //用指针p指向第theIndex-1个节点
		chainNode<T> *p = firstNode;
		for (int i = 0; i<theIndex - 1; i++)
			p = p->next;
		deleteNode = p->next;
		p->next = p->next->next;//删除deleteNode指向的节点
	} listSize--;
	delete deleteNode;
}//删除链表中索引值的节点
template<class T>
void chain<T>::insert(int theIndex, const T& theElement)
{

	//在链表表头插入
	if (theIndex == 0) firstNode = new chainNode<T>(theElement, firstNode);
	else
	{//寻找新元素的前驱(第theIndex-1个元素 )
		chainNode<T> *p = firstNode;
		for (int i = 0; i < theIndex - 1; i++)
			p = p->next; //将p移动至第theIndex-1个元素
		//在p之后插入
		p->next = new chainNode<T>(theElement, p->next);
	}
	listSize++;
}//在链表中插入一个数
template<class T>
chain<T> combine(chain<T>&a, chain<T>&b){
	chain<T>c;
	int flag = 0;
	Iterator<T> i = a.begin();
	Iterator<T> j = a.end();
	Iterator<T> k = b.begin();
	Iterator<T> n = b.end();
	while (i != j){
		c.insert(flag, (*i));
		i++;
		flag++;
	}
	while (k != n){
		c.insert(flag,(*k));
		k++;
		flag++;
	}
	return c;
}
template<class T>
void  chain<T>::reverse(){
	if (listSize <= 1)return;
	chainNode<T>* pre = NULL;
	chainNode<T>*next = NULL;
	chainNode<T>*head = firstNode;
	while (head != NULL)
	{
		next = head->next;
		head->next = pre;
		pre = head;
		head = next;
	}
	firstNode = pre;
}//逆置链表

int main(){
	int N, M, flag;
	cin >> N >> M;
	chain<int>a;
	chain<int>b;
	chain<int>x;
	chain<int>y;
	
	for (int i = 0; i <N; i++)
	{
		cin >> flag;
		a.insert(i, flag);
	}
	int *c = a.transpose();
	for(int i = 0; i < N; i ++){
		x.insert(i,c[i]);
	}
	for (int i = 0; i <M; i++)
	{
		cin >> flag;
		b.insert(i, flag);
	}
	chain<int>e = combine(c, d);
	int *d = b.transpose();
		for(int i = 0; i < M; i ++){
		y.insert(i,d[i]);
	}
	int *f=e.transpose();


	int res = yihuoSum(c, N);
	int res2 = yihuoSum(d, M);
	int res3=yihuoSum(f,M+N);
	
		cout<<res<<endl;
	cout<<res2<<endl;
		cout<<res3<<endl;
	return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咕噜咕噜咕噜128

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值