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