数据结构(链表)

1. 实验一 顺序表

【问题描述】请阅读以下顺序表的实现代码,完善并实现顺序表的插入和删除操作。
【举例】

请输入顺序表的最大长度:20

请输入顺序表的数据的个数:5

请依次输入5个数据:2 4 6 8 10

请输入插入数据的位置和数值:2 3

执行插入操作后的顺序表:2 3 4 6 8 10

请输入删除数据的位置:3

执行删除操作后的顺序表:2 3 6 8 10

#include<iostream>
#include<stdlib.h>
using  namespace  std;
class  seqlist {
    
    
	private:
		int  *listP;
		int  maxsize;
		int  sizeL;
	public:
		seqlist(int  maxL);
		~seqlist();
		int  getSize();
		void  Insert(int  i,int  item);
		int  Delete(  int  i);
		int  getdata(int  i);
		void  dispaly(  );
};
//初始化顺序表
seqlist::seqlist(int  maxL) {
    
    
	maxsize=maxL;
	sizeL=0;
	listP=new  int[maxL];
}
//释放顺序表的空间
seqlist::~seqlist() {
    
    
	delete  []listP;
	maxsize=0;
	sizeL=0;
}
//返回顺序表的长度
int  seqlist::getSize() {
    
    
	return  sizeL;
}
//在位置i处插入元素item
void  seqlist::Insert(  int  i,int  item) {
    
    
	sizeL++;
	for(int j=sizeL; j>i; j--) {
    
    
		listP[j]=listP[j-1];
	}
	listP[i]=item;
}
//先返回位置i处的数据,在删除该数据
int  seqlist::Delete(  int  i) {
    
    
	int x=listP[i];
	for(int j=i; j<sizeL; j++) {
    
    
		listP[j]=listP[j+1];
	}
	sizeL--;
	return x;
}
//返回位置i处的数据
int  seqlist::getdata(int  i) {
    
    
	if(i<1  ||  i>sizeL) {
    
    
		cout<<"参数越界错误!";
		exit(0);
	}
	return  listP[i];
}
//打印顺序表
void  seqlist::dispaly(  ) {
    
    
	for(int  i=1; i<=sizeL; i++)
		cout<<listP[i]<<"    ";
	cout<<endl;
}

int  main() {
    
    
	int  maxL=0,n=0,item,pos;
	//cout<<"请输入顺序表的最大长度:";
	cin>>maxL;
	seqlist  mylist(maxL);
	//cout<<"请输入顺序表的数据的个数:";
	cin>>n;
	//  cout<<"请依次输入"<<n<<"个数据:";
	for(int  i=0; i<n; i++) {
    
    
		cin>>item;
		mylist.Insert(i+1,item);//插入下标从1开始
	}
	//cout<<"请输入插入数据的位置和数值:";
	cin>>pos>>item;
	mylist.Insert(pos,item);
	//  cout<<"执行插入操作后的顺序表:";
	mylist.dispaly();
	//cout<<"请输入删除数据的位置:";
	cin>>pos;
	mylist.Delete(pos);
	//cout<<"执行删除操作后的顺序表:";
	mylist.dispaly();
	return  1;
}

2. 删除顺序表元素

在顺序表中删除所有元素值为x的元素,要求空间复杂度为O(1)。

#include  <iostream>
using  namespace  std;

const  int  MaxSize=100;
typedef  int  DataType;
DataType  data[MaxSize];
int  length;

void  deleteList(DataType  elem) {
    
    
	int i=0,j=0;
	while(i<length) {
    
    
		if(data[i]==elem)
			j++;//j记录被删记录的个数
		else
			data[i-j]=data[i];//前移j个位置
		i++;
	}
	length-=j;

}
void  show() {
    
    
	for(int  i=0; i<length; ++i)
		cout<<data[i]<<"  ";
	cout<<endl;
}
int  main() {
    
    
	cin>>length;
	for(int  i=0; i<length; ++i)
		cin>>data[i];
	DataType  x;
	cin>>x;
	deleteList(x);
	show();
	return  0;
}

3. 删除单链表中大于minK且小于maxK的元素

已知单链表中各结点的元素值为整型且自增有序,设计算法删除单链表中大于minK且小于maxK的所有元素,并释放被删结点的存储空间。

#include  <iostream>
using  namespace  std;

typedef  int  DataType;
typedef  struct  node {
    
    
	DataType  data;
	node*  next;
} node;
node  *first;

void  init(  ) {
    
    
	first  =  new  node;//带头节点
	first->next  =  NULL;
	node*  rear  =  first;
	int  length;
	cin>>length;
	for(int  i=0; i<length; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node*  s  =  new  node;
		s->data  =  elem;
		s->next  =  NULL;
		rear->next  =  s;//尾插法
		rear  =  s;
	}
}
void  deleteList(DataType  minK,DataType  maxk) {
    
    
	node *p=first;//获取头节点
	while(p->next&&(p->next->data)<=minK) {
    
     //找到最小值mink的位置
		p=p->next;
	}
	while(p->next&&(p->next->data)<maxk) {
    
     //删除小于最大值maxk的结点 
		node *q=p->next;//q为需要删除的结点 
		if(q!=NULL) {
    
      
			p->next=q->next; //断链 
			delete q; //释放内存 
		} else {
    
    
			delete q;
		}
	}

}
void  show(  ) {
    
    
	node*  p  =  first->next;
	if(p  ==  NULL)  cout<<"Empty";
	while(p  !=  NULL) {
    
    
		cout<<p->data<<"  ";
		p  =  p->next;
	}
	cout<<endl;
}
int  main() {
    
    
	init();
	DataType  minK,maxK;
	cin>>minK>>maxK;
	deleteList(minK,maxK);
	show();
	return  0;
}


4. 顺序表插入并递增有序

已知顺序表L中的元素递增有序排列,设计算法将元素x插入到表L中并保持表L仍递增有序。

#include  <iostream>
using  namespace  std;

const  int  MaxSize=100;
typedef  int  DataType;
DataType  data[MaxSize];
int  length=0;

void  insertList(DataType  elem) {
    
    
	int i;
	for(i=0; i<length; i++) {
    
    //找出插入点下标 i
		if(data[i]>=elem)
			break;
	}
	for(int j=length; j>i; j--) {
    
    
		data[j]=data[j-1];
	}
	data[i]=elem;
	length++;
}
void  show() {
    
    
	for(int  i=0; i<length; ++i)
		cout<<data[i]<<"  ";
	cout<<endl;

}
int  main() {
    
    
	cin>>length;
	for(int  i=0; i<length; ++i)
		cin>>data[i];
	DataType  x;
	cin>>x;
	insertList(x);
	show();
	return  0;
}

5. 顺序表逆置

以顺序表存储非空线性表,编写一个实现线性表就地逆置的算法。空间复杂度均是O(1)。

#include  <iostream>
using  namespace  std;

const  int  MaxSize=100;
typedef  int  DataType;
DataType  data[MaxSize];
int  length;

void  reverseList(  ) {
    
    
	int first=0;
	while(first<length/2) {
    
     //最多交换length/2次
		DataType temp;
		temp=data[first]; //交换首位的值
		data[first]=data[length-1-first];
		data[length-1-first]=temp;
		first++;
	}

}
void  show() {
    
    
	for(int  i=0; i<length; ++i)
		cout<<data[i]<<"  ";
	cout<<endl;
}
int  main() {
    
    
	cin>>length;
	for(int  i=0; i<length; ++i)
		cin>>data[i];
	reverseList();
	show();
	return  0;
}

6. 单链表逆置

以单链表作存储结构存储非空线性表,编写一个实现线性表就地逆置的算法。空间复杂度均是O(1)。

#include  <iostream>
using  namespace  std;

typedef  int  DataType;
typedef  struct  node {
    
    
	DataType  data;
	node*  next;
} node;
node*  first;
int  length;

void  init() {
    
    
	first  =  new  node;
	first->next  =  NULL;
	node*  rear  =  first;
	cin>>length;
	for(int  i=0; i<length; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node*  s  =  new  node;
		s->data  =  elem;
		s->next  =  NULL;
		rear->next  =  s;
		rear  =  s;
	}
}
void  reverseList() {
    
    
	// 采用头插法实现逆置
	node *p,*q;
	p=first->next; //记录第一个结点
	first->next=NULL; //断链,重新插入
	while(p) {
    
    
		/*向后挪动一个位置*/
		q=p;
		p=p->next;
		/*头插*/
		q->next=first->next;
		first->next=q;
	}
}
void  show() {
    
    
	node*  p  =  first->next;
	while(p  !=  NULL) {
    
    
		cout<<p->data<<"  ";
		p  =  p->next;
	}
	cout<<endl;
}
int  main() {
    
    
	init();
	reverseList();
	show();
	return  0;
}

7. 逆序打印单链表

写一个函数,逆序打印单链表中的数据(单链表是带有头结点的单链表)。

#include  <iostream>
using  namespace  std;

template  <class  DataType>
struct  node {
    
    
	DataType  data;
	node<DataType>*  next;
};

template  <class  DataType>
class  linkList {
    
    
	public:
		linkList();
		~linkList();
		node<DataType>*  getFirst();
		void  reversePrint(node<DataType>*  p);
	private:
		node<DataType>*  first;
};

template  <class  DataType>
linkList<DataType>::linkList() {
    
    
	first  =  new  node<DataType>;
	first->next  =  NULL;
	node<DataType>*  rear  =  first;
	int  n;
	cin>>n;
	for(int  i=0; i<n; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node<DataType>*  s  =  new  node<DataType>;
		s->data  =  elem;
		s->next  =  NULL;
		rear->next  =  s;
		rear  =  s;
	}
}
template  <class  DataType>
linkList<DataType>::~linkList() {
    
    
	node<DataType>*  p;
	while(first  !=  NULL) {
    
    
		p  =  first;
		first  =  first->next;
		delete  p;
	}
}

template  <class  DataType>
node<DataType>*  linkList<DataType>::getFirst() {
    
    
	return  first;
}

template  <class  DataType>
void  linkList<DataType>::reversePrint(node<DataType>*  p) {
    
    //采用数组记录 
	DataType ans[100];
	int i=0;
	while(p) {
    
    
		ans[i]=p->data;
		p=p->next;
		i++;
	}
	for(int j=i-1; j>=0; j--)
		cout<<ans[j]<<" ";
}
int  main() {
    
    
	linkList<int>  L;
	node<int>*  p  =  L.getFirst()->next;
	if(p  ==  NULL)
		cout<<"Empty"<<endl;
	else
		L.reversePrint(p);
	L.~linkList();
	return  0;
}


8. 单链表删除重复数值

有一个递增非空单链表,设计一个算法删除值域重复的结点。例如{1,1,2,3,3,3,4,4,7,7,7,9,9,9,},经过删除后变成{1,2,3,4,7,9}。

#include  <iostream>
using  namespace  std;

template  <class  DataType>
struct  node {
    
    
	DataType  data;
	node<DataType>*  next;
};

template  <class  DataType>
class  linkList {
    
    
	public:
		linkList();
		~linkList();
		void  Delete();
		void  show();
	private:
		node<DataType>*  first;
};

template  <class  DataType>
linkList<DataType>::linkList() {
    
    
	first  =  new  node<DataType>;
	first->next  =  NULL;
	node<DataType>*  rear  =  first;
	int  n;
	cin>>n;
	for(int  i=0; i<n; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node<DataType>*  s  =  new  node<DataType>;
		s->data  =  elem;
		s->next  =  NULL;
		rear->next  =  s;
		rear  =  s;
	}
}
template  <class  DataType>
linkList<DataType>::~linkList() {
    
    
	node<DataType>*  p;
	while(first  !=  NULL) {
    
    
		p  =  first;
		first  =  first->next;
		delete  p;
	}
}
template  <class  DataType>
void  linkList<DataType>::Delete() {
    
    
	node<DataType> *q,*p;
	q=first->next; //q记录前驱 p记录后继
	p=q->next;
	while(p) {
    
    
		if(q->data==p->data) {
    
     //满足重复条件删除结点
			q->next=p->next;
			p=q->next;
		} else {
    
    
			q=p;
			p=p->next;
		}
	}

}

template  <class  DataType>
void  linkList<DataType>::show() {
    
    
	node<DataType>*  p  =  first->next;
	if(p  ==  NULL)  cout<<"Empty";
	else {
    
    
		while(p  !=  NULL) {
    
    
			cout<<p->data<<"  ";
			p  =  p->next;
		}
		cout<<endl;
	}
}
int  main() {
    
    
	linkList<int>  L;
	L.Delete();
	L.show();
	L.~linkList();
	return  0;
}

9. 单链表应用:八进制求和

假设用不带头结点的单链表表示八进制数,例如八进制数536表示成如图所示单链表。要求写一个函数Add,该函数有两个参数A和B,分别指向表示八进制的单链表,执行函数调用Add(A,B)后,得到表示八进制A加八进制B所得结果的单链表,结果保留在单链表A中。

【输入说明】A表的长度和A表中八进制的数码;(中间用空格隔开)
B表的长度和B表中八进制的数码;(中间用空格隔开)

【输出说明】八进制A加八进制B所得结果

3

5 3 6

2

5 4

【输出样例】

612
#include  <iostream>
using  namespace  std;

typedef  int  DataType;
typedef  struct  node {
    
    
	DataType  data;
	node*  next;
} node;

//尾插法构造单链表
void  init(node*&first,int  len) {
    
    
	first  =  NULL;
	node*  rear;
	for(int  i=0; i<len; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node*  s  =  new  node;
		s->data  =  elem;
		s->next  =  NULL;
		if(first  ==  NULL) {
    
    
			first  =  s;
			rear  =  first;
		} else {
    
    
			rear->next  =  s;
			rear  =  s;
		}
	}
}
//八进制A加八进制B,结果存在链表A中
void  add(node*  A,node*  B) {
    
    
	node *p=A,*q=B,*pre=NULL,*qre=NULL;
	int flag=0;
	while(p&&q) {
    
    
		int sum=p->data+q->data+flag;
		p->data=sum%8;
		flag=sum/8;
		pre=p;
		p=p->next;
		qre=q;
		q=q->next;
	}
	if(q) {
    
    
		qre->next=NULL;
		p=q;
		pre->next=p;
	}
	while(p) {
    
    
		int sum=p->data+flag;
		p->data=sum%8;
		flag=sum/8;
		pre=p;
		p=p->next;
	}
	if(flag) {
    
    
		node *s=new node;
		s->data=flag;
		s->next=NULL;
		pre->next=s;
	}
}

void  reverseList(node*  &first) {
    
     //这是个不带头结点的链表
	node *p,*q,*m;
	p=first;
	q=p->next;
	m=q->next;
	p->next=NULL; //断第一个结点的链
	while(q) {
    
    
		q->next=p;
		first=q;
		p=q;
		q=m;
		if(m!=NULL)
			m=m->next;
	}

}
void  show(node*  first) {
    
    
	node*  p  =  first;
	if(p  ==  NULL)  cout<<"Empty";
	else {
    
    
		while(p  !=  NULL) {
    
    
			cout<<p->data;
			p  =  p->next;
		}
		cout<<endl;
	}
}
int  main() {
    
    
	node*A,*B;
	int  aLen,bLen;
	cin>>aLen;
	init(A,aLen);
	cin>>bLen;
	init(B,bLen);

	reverseList(A);

	reverseList(B);

	add(A,B);
	reverseList(A);
	show(A);
	return  0;
}

10. 查找单链表倒数第k个结点

【问题描述】输入一个单向链表,输出该链表中倒数第k个结点,链表的最后一个结点是倒数第1个节点。

【输入形式】第一行是数据的个数,第二行是空格分割的整型值,第三行是K值。

【输出形式】输出为倒数第K个结点的值,若无,则输出Not Found。

【样例输入】

8
13 45 54 32 1 4 98 2
3

【样例输出】4

【样例说明】K值为3,则输出链表倒数第3个结点的值,为4;数据输入间以空格隔开

#include  <iostream>
using  namespace  std;

template  <class  DataType>
struct  node {
    
    
	DataType  data;
	node<DataType>*  next;
};

template  <class  DataType>
class  linkList {
    
    
	public:
		linkList();
		~linkList();
		node<DataType>*  reverseFindK(int  k);
	private:
		node<DataType>*  first;
};

template  <class  DataType>
linkList<DataType>::linkList() {
    
    
	first  =  new  node<DataType>;
	first->next  =  NULL;
	node<DataType>*  rear  =  first;
	int  n;
	cin>>n;
	for(int  i=0; i<n; ++i) {
    
    
		DataType  elem;
		cin>>elem;
		node<DataType>*  s  =  new  node<DataType>;
		s->data  =  elem;
		s->next  =  NULL;
		rear->next  =  s;
		rear  =  s;
	}
}
template  <class  DataType>
linkList<DataType>::~linkList() {
    
    
	node<DataType>*  p;
	while(first  !=  NULL) {
    
    
		p  =  first;
		first  =  first->next;
		delete  p;
	}
}

template  <class  DataType>
node<DataType>*  linkList<DataType>::reverseFindK(int  k) {
    
    
	//头插法逆置单链表
	node<DataType> *p,*q;
	p=first->next;
	first->next=NULL;
	while(p) {
    
    
		q=p;
		p=p->next;
		q->next=first->next;
		first->next=q;
	}
	p=first->next;
	int i=1;
	while(i<k) {
    
    //查找第k个结点
		i++;
		p=p->next;
	}
	return p;

}
int  main() {
    
    
	linkList<int>  L;
	int  k;
	cin>>k;
	node<int>*  p  =  L.reverseFindK(k);
	if(p  ==  NULL)
		cout<<"Not  Found"<<endl;
	else
		cout<<p->data<<endl;
	L.~linkList();
	return  0;
}


11. 双循环链表是否对称

判断带头结点的双循环链表是否对称。

#include  <iostream>
using  namespace  std;

typedef  int  DataType;
typedef  struct  node {
    
    
	DataType  data;
	node*  next,*prior;
} node;
node*  first;

void  init(  ) {
    
    
	first  =  new  node;//带有头节点的双循环链表
	first->next  =  NULL;
	first->prior  =  NULL;
	node*  rear  =  first;
	DataType  elem;
	while(cin>>elem) {
    
    
		node*  s  =  new  node;
		s->data  =  elem;
		s->next  =  NULL;
		s->prior  =  rear;
		rear->next  =  s;
		rear  =  s;
	}
	rear->next  =  first;
	first->prior  =  rear;
}
bool  equalDulList() {
    
    
	node *head,*end;
	head=first->next;//第一个结点
	end=first->prior;//最后一个结点
	while(head->next!=end&&head!=end) {
    
    //有结点数目为奇数个的情况与偶数的情况
		if(head->data!=end->data)
			return false;
		else {
    
    
			head=head->next;
			end=end->prior;
		}
	}
	if(head->data!=end->data)//如果满足条件的话不管哪种情况最终head与end所指的数据都相等
		return false;
	return true;


}
void  show() {
    
    
	node*  p  =  first->next;
	while(p  !=  first) {
    
    
		cout<<p->data<<"  ";
		p  =  p->next;
	}
	cout<<endl;
}
int  main() {
    
    
	init();
	//show();
	bool  res  =  equalDulList();
	if(res)  cout<<"YES"<<endl;
	else  cout<<"NO"<<endl;
	return  0;
}

结语

如果你发现文章有什么问题,欢迎留言指正。
如果你觉得这篇文章还可以,别忘记点个赞加个关注再走哦。
如果你不嫌弃,还可以关注微信公众号———梦码城(持续更新中)。
梦码在这里感激不尽!!

猜你喜欢

转载自blog.csdn.net/qq_45724216/article/details/112132578