数据结构与算法实验4——链式描述线性表

1.实验内容

实验4.1

要求封装链表类,链表迭代器类;

链表类需提供操作:在指定位置插入元素,删除指定元素,搜索链表中是否有指定元素,原地逆置链表,输出链表;

不得使用与链表实现相关的STL。

输入输出格式:

输入:第一行两个整数 N 和 Q。

第二行 N 个整数,作为节点的元素值,创建链表。

接下来 Q 行,执行各个操作,具体格式如下:

插入操作 : 1 idx val,在链表的idx位置插入元素val;

删除操作 : 2 val,删除链表中的 val 元素。若链表中存在多个该元素,仅删除第一个。若该元素不存在,输出 -1;

逆置操作 : 3,原地逆置链表;

查询操作 : 4 val,查询链表中的val元素,并输出其索引。若链表中存在多个该元素,输出第一个的索引。若不存在该元素,输出 -1;

输出操作 : 5,使用链表迭代器,输出当前链表索引与元素的异或和。

实验4.2

要求使用题目一中实现的链表类,迭代器类完成本题;

不得使用与题目实现相关的STL;

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

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

输入输出格式:

输入:

第一行两个整数 N 和 M;

第二行 N 个整数,代表第一组整数序列;

第三行 M 个整数,代表第二组整数序列。

输出:

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

2.测试结果

实验4.1

输入:

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

输出:
0
398665

-1

410141

5

410141

0

实验4.2

输入:

3 2

3 1 2

8 7

输出:

5

16

21

3.源代码

实验4.1

#include<iostream>

using namespace std;

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 chain

{

public:

chain() //构造函数

{

firstNode=NULL;

listSize=0;

}

chain(const chain<T>&theList) //复制构造函数

{

listSize=theList.listSize;

if(listSize==0)

{

firstNode=NULL;

return;

}

chainNode<T>*sourceNode=theList.firstNode;

firstNode=new chainNode<T>(sourceNode->element);

sourceNode=sourceNode->next;

chainNode<T>*targetNode=firstNode;

while(sourceNode!=NULL)

{

targetNode->next=new chainNode<T>(sourceNode->element);

targetNode=targetNode->next;

sourceNode=sourceNode->next;

}

targetNode->next=NULL;

}

~chain() //析构函数

{

while(firstNode)

{

chainNode<T>*next=firstNode->next;

delete firstNode;

firstNode=next;

}

}

class iterator //定义迭代器

{

public:

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;

};

iterator begin() {return iterator(firstNode);}      //迭代器类型函数begin()

iterator end() {return iterator(NULL);}  //迭代器类型函数end()

T& get(int theIndex) const //获取索引处的元素

{

chainNode<T>*currentNode=firstNode;

for(int i=0;i<theIndex;i++) currentNode=currentNode->next;

return currentNode->element;

}

int indexOf(const T &theElement) const //获取值为该元素的索引

{

chainNode<T>*currentNode=firstNode;

int index=0;

while(currentNode!=NULL && currentNode->element!=theElement)

{

currentNode=currentNode->next;

index++;

}

if(currentNode==NULL) return -1;

return index;

}

void erase(int theIndex) //删除节点

{

chainNode<T>*deleteNode=firstNode;

if(theIndex==0)

{

deleteNode=firstNode;

firstNode=firstNode->next;

}

else

{

chainNode<T>*p=firstNode;

for(int i=0;i<theIndex-1;i++) p=p->next;

deleteNode=p->next;

p->next=p->next->next;

}

listSize--;

delete deleteNode;

}

void insert(int theIndex,const T &theElement) //插入节点

{

if(theIndex==0) firstNode=new chainNode<T>(theElement,firstNode);

else

{

chainNode<T>*p=firstNode;

for(int i=0;i<theIndex-1;i++) p=p->next;

p->next=new chainNode<T>(theElement,p->next);

}

listSize++;

}

void outPut(ostream &out) const //输出链表

{

for(chainNode<T>*currentNode=firstNode;currentNode!=NULL;currentNode=currentNode->next)

out<<currentNode->element<<" ";

}

void reverse() //逆置链表

{

if(firstNode==NULL||firstNode->next==NULL) return;

chainNode<T>*pastNode=firstNode;

chainNode<T>*currentNode=pastNode->next;

chainNode<T>*futureNode=currentNode->next;

firstNode->next=NULL;

while(futureNode!=NULL)

{

currentNode->next=pastNode;

pastNode=currentNode;

currentNode=futureNode;

futureNode=futureNode->next;

}

currentNode->next=pastNode;

firstNode=currentNode;

}

int sum() //计算链表索引与元素的异或和

{

int S=0,index=0;

iterator beginning=begin();

while(index<listSize)

{

S+=index^(*beginning);

beginning++;

index++;

}

return S;

}

void combine(chain<T>&L1,chain<T>&L2) //将链表赋值为两个链表的有序连接

{

if(listSize>0) for(int i=0;i<listSize;i++) erase(0);

iterator current1=L1.begin();

iterator current2=L2.begin();

for(int i=0;i<L1.listSize+L2.listSize;)

{

if(current1==NULL)

{

insert(i,*current2);

current2++;

i++;

continue;

}

if(current2==NULL)

{

insert(i,*current1);

current1++;

i++;

continue;

}

if((*current1)<(*current2))

{

insert(i,*current1);

current1++;

i++;

}

else if((*current1)>(*current2))

{

insert(i,*current2);

current2++;

i++;

}

else

{

insert(i,*current1);

i++;

insert(i,*current2);

current1++;

current2++;

i++;

}

}

}

private:

chainNode<T>*firstNode; //链表的头指针

int listSize; //链表的长度

};

int main()

{

int N,Q;

cin>>N>>Q; //输入N和Q

int *a=new int[N];

for(int i=0;i<N;i++) cin>>a[i]; //输入节点元素值

chain<int>Array; //创建链表

for(int i=0;i<N;i++) Array.insert(i,a[i]); //插入各节点

delete []a;

for(int i=0;i<Q;i++) //执行Q次操作

{

int choice;

cin>>choice; //输入操作序号

int idx,val,index;

switch(choice)

{

case 1:

cin>>idx>>val; //输入1时,输入idx与val

Array.insert(idx,val); //在idx处插入元素val

break;

case 2:

cin>>val; //输入2时,输入val

index=Array.indexOf(val); //查找val的位置

if(index!=-1) Array.erase(index); //若存在,删除该元素

else cout<<"-1"<<endl; //若不存在,输出-1

break;

case 3:

Array.reverse(); //输入3时,原地逆置链表

break;

case 4:

cin>>val; //输入4时,输入val

cout<<Array.indexOf(val)<<endl; //查询val的位置

break;

case 5:

cout<<Array.sum()<<endl; //输入5时,输出异或和

break;

default:

break;

}

}

return 0;

}

实验4.2

#include<iostream>

using namespace std;

template<class T>

void compare(T *a,int n,int *r)//比较函数,计算数组a中每个元素的名次,将名次存入数组r中

{

int i,j;

for(i=0;i<n;i++)

{

int k=0;

for(j=0;j<n;j++) if((j<i&&a[j]==a[i])||a[j]<a[i]) k++;

//计算比a[i]小或者与a[i]相等但在a[i]左侧的元素个数并记入k

r[i]=k; //将名次k赋值给r[i]

}

}

template<class T>

void makeOrder(T *a,int n) //名次排序,数组a记录n个元素

{

int *r=new int[n];

compare(a,n,r); //用数组r记录n个元素的名次

T *b=new T[n];

int i;

for(i=0;i<n;i++) b[r[i]]=a[i]; //将元素按顺序记录在数组b中

for(i=0;i<n;i++) a[i]=b[i]; //将元素按顺序转存在数组a中

delete []b;

delete []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 chain

{

public:

chain() //构造函数

{

firstNode=NULL;

listSize=0;

}

chain(const chain<T>&theList) //复制构造函数

{

listSize=theList.listSize;

if(listSize==0)

{

firstNode=NULL;

return;

}

chainNode<T>*sourceNode=theList.firstNode;

firstNode=new chainNode<T>(sourceNode->element);

sourceNode=sourceNode->next;

chainNode<T>*targetNode=firstNode;

while(sourceNode!=NULL)

{

targetNode->next=new chainNode<T>(sourceNode->element);

targetNode=targetNode->next;

sourceNode=sourceNode->next;

}

targetNode->next=NULL;

}

~chain() //析构函数

{

while(firstNode)

{

chainNode<T>*next=firstNode->next;

delete firstNode;

firstNode=next;

}

}

class iterator //定义迭代器

{

public:

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;

};

iterator begin() {return iterator(firstNode);} //迭代器类型函数begin()

iterator end() {return iterator(NULL);} //迭代器类型函数end()

T& get(int theIndex) const //获取索引处的元素

{

chainNode<T>*currentNode=firstNode;

for(int i=0;i<theIndex;i++) currentNode=currentNode->next;

return currentNode->element;

}

int indexOf(const T &theElement) const //获取值为该元素的索引

{

chainNode<T>*currentNode=firstNode;

int index=0;

while(currentNode!=NULL && currentNode->element!=theElement)

{

currentNode=currentNode->next;

index++;

}

if(currentNode==NULL) return -1;

return index;

}

void erase(int theIndex) //删除节点

{

chainNode<T>*deleteNode=firstNode;

if(theIndex==0)

{

deleteNode=firstNode;

firstNode=firstNode->next;

}

else

{

chainNode<T>*p=firstNode;

for(int i=0;i<theIndex-1;i++) p=p->next;

deleteNode=p->next;

p->next=p->next->next;

}

listSize--;

delete deleteNode;

}

void insert(int theIndex,const T &theElement) //插入节点

{

if(theIndex==0) firstNode=new chainNode<T>(theElement,firstNode);

else

{

chainNode<T>*p=firstNode;

for(int i=0;i<theIndex-1;i++) p=p->next;

p->next=new chainNode<T>(theElement,p->next);

}

listSize++;

}

void outPut(ostream &out) const //输出链表

{

for(chainNode<T>*currentNode=firstNode;currentNode!=NULL;currentNode=currentNode->next)

out<<currentNode->element<<" ";

}

void reverse() //逆置链表

{

if(firstNode==NULL||firstNode->next==NULL) return;

chainNode<T>*pastNode=firstNode;

chainNode<T>*currentNode=pastNode->next;

chainNode<T>*futureNode=currentNode->next;

firstNode->next=NULL;

while(futureNode!=NULL)

{

currentNode->next=pastNode;

pastNode=currentNode;

currentNode=futureNode;

futureNode=futureNode->next;

}

currentNode->next=pastNode;

firstNode=currentNode;

}

int sum() //计算链表索引与元素的异或和

{

int S=0,index=0;

iterator beginning=begin();

while(index<listSize)

{

S+=index^(*beginning);

beginning++;

index++;

}

return S;

}

void combine(chain<T>&L1,chain<T>&L2) //将链表赋值为两个链表的有序连接

{

if(listSize>0) for(int i=0;i<listSize;i++) erase(0);

iterator current1=L1.begin();

iterator current2=L2.begin();

for(int i=0;i<L1.listSize+L2.listSize;)

{

if(current1==NULL)

{

insert(i,*current2);

current2++;

i++;

continue;

}

if(current2==NULL)

{

insert(i,*current1);

current1++;

i++;

continue;

}

if((*current1)<(*current2))

{

insert(i,*current1);

current1++;

i++;

}

else if((*current1)>(*current2))

{

insert(i,*current2);

current2++;

i++;

}

else

{

insert(i,*current1);

i++;

insert(i,*current2);

current1++;

current2++;

i++;

}

}

}

private:

chainNode<T>*firstNode; //链表的头指针

int listSize; //链表的长度

};

int main()

{

int N,M;

cin>>N>>M;

int *a1=new int[N];

for(int i=0;i<N;i++) cin>>a1[i];   //输入Array1的节点元素值

makeOrder(a1,N); //使元素有序

chain<int>Array1; //创建链表

for(int i=0;i<N;i++) Array1.insert(i,a1[i]); //插入各节点

int *a2=new int[M];

for(int i=0;i<M;i++) cin>>a2[i]; //输入Array2的节点元素值

makeOrder(a2,M); //使元素有序

chain<int>Array2; //创建链表

for(int i=0;i<M;i++) Array2.insert(i,a2[i]); //插入各节点

chain<int>Array;

Array.combine(Array1,Array2); //将连接结果存入Array

cout<<Array1.sum()<<endl; //输出Array1的异或和

cout<<Array2.sum()<<endl; //输出Array2的异或和

cout<<Array.sum()<<endl; //输出Array的异或和

delete []a1;

delete []a2;

return 0;

}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值