第二章 线性表
1.顺序表
插入操作
template <typename DataType>
void SeqList<DataType>::Insert(int i,DataType x) //插入操作
{
if(length==MaxSize) exit(0); //上溢
if(i<1 || i>length+1) exit(0); //插入位置错误
for(int j=length;j>=i;j--)
{
data[j]=data[j-1]; //data数组是从0开始存储的 到时候看输出方法来判断是怎么存入的 //data[j+1]=data[j] data数组从1开始存储
}
data[i-1]=x; //data[i]=x;
length++;
}
删除操作
template <typename DataType>
int Seqlist<DataType::Delete( int i) //删除操作
{
DataType x;
if(length==0) exit(0); //下溢
if(i<1 || i>length)exit(0); //删除位置错误
x=data[i-1]; //x=data[i];
for(int j=i;j<length;j++) //for(int j=i;j<length;j++)
{
data[j-1]=data[j]; //data[j]=data[j+1];
}
length--;
return x;
}
2.删除顺序表元素
在顺序表中删除所有元素值为x的元素
#include <iostream>
using namespace std;
const int MaxSize=100;
typedef int DataType;
DataType data[MaxSize];
int length;
void deleteList(DataType elem)
{
for(int i=0;i<length;i++)
{
if(data[i]==elem)
{
for(int j=i;j<length;j++)
data[j]=data[j+1];
length--;
i--; //i--后到被删除元素的前一个位置,然后for循环还有个i++
}
}
}
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.顺序表插入并递增有序
已知顺序表L中的元素递增有序排列,设计算法将元素x插入到表L中并保持表L仍递增有序。
void inserList(DataType elem)
{
int i=0;
for(i=0;i<length;i++)
{
if(data[i]>elem)
{
for(int j=length;j>=i;j--)
{
data[j]=data[j-1];
}
break;
}
}
data[i]=elem; //移动完成后,i+1的位置是原来i的值>elem,所以在下角标为i的地方插入elem
length++;
4.顺序表逆置
void reverseList() //顺序表逆置
{
for(int i=0,j=length-1;i<=(length-1)/2;i++,j--) //i<=(length-1)/2
{
int temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
单链表逆置
void reverseList() //单链表逆置
{
node* p=first->next;
node* q=NULL;
first->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=first->next; //将p所在的结点取下,插入头结点后面,先右后左
first->next=p;
p=q;
}
}
5.逆序打印单链表
#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) //逆序打印
{
node<DataType>* q=NULL;
first->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=first->next;
first->next=p;
p=q;
}
//开始打印
p=first->next;
while(p!=NULL)
{
cout<<p->data<<" ";
p=p->next;
}
cout<<endl;
}
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;
}
6.查找单链表倒数第k个结点
template <class DataType>
node<DataType>* linkList<DataType>::reverseFindK(int k)
{
node<DataType>* p=first->next;
node<DataType>* q=NULL;
first->next=NULL;
while(p!=NULL)
{
q=p->next;
p->next=first->next;
first->next=p;
p=q;
}
node<DataType>* r=first;
r=first->next;
int count=1;
//先找到k的前一个,然后执行r=r->next;count++;然后退出循环,即得所要结点
while(r!=NULL&&count<k)
{
r=r->next;
count++;
}
return r;
}
7.删除单链表中大于minK且小于maxK的元素
void deleteList(DataType minK,DataType maxK)
{
node* q=first; //q指针一直在p指针的前一个
node* p=q->next;
while(p!=NULL && p->data<=minK)
{
q=p; //先移动q,再移动P
p=q->next;
}
while(p!=NULL && p->data<maxK)
{
q->next=p->next;
delete p;
p=q->next;
}
}
8.单链表删除重复数值
template <class DataType>
void linkList<DataType>::Delete()
{
node<DataType>* p = first->next;
node<DataType>* q =NULL;
//因为要与p->next的data域里的数值作比较,所以p->next也不能为空
while(p != NULL && p->next != NULL)
{
if(p->data == p->next->data)
{
q = p->next;
p->next = q->next;
delete q;
}
else
{
p=p->next;
}
}
}
9.单链表应用:八进制求和 (add方法是自己想的,过程极其复杂,有很多重复的操作)
假设用不带头结点的单链表表示八进制数。要求写一个函数Add,该函数有两个参数A和B,分别指向表示八进制的单链表,执行函数调用Add(A,B)后,得到表示八进制A加八进制B所得结果的单链表,结果保留在单链表A中。
#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; //这里相当于p指向了链表A的第一个结点
node* q=B;
node* pre=p;
while(p!=NULL && q!=NULL)
{
DataType r=p->data+q->data;
if(r>=8)
{
p->data=r-8;
if(p->next!=NULL) //p的下一个不为空
{
p->next->data++;
}
else if(q->next!=NULL) //p的下一个为空,q的下一个不为空
{
q->next->data++;
}
else //p的下一个和q的下一个都为空,那么就新建一个,插入A链表中
{
node* s=NULL;
s=new node;
s->next=NULL;
s->data=1;
p->next=s;
}
}
pre=p; //向后移动,先右后左
p=p->next;
q=q->next;
}
if(q!=NULL) //如果p为空了,退出循环,q不为空,此时pre=p,p=p->next=NULL;
{
pre->next=q;
if(q->data>=8)
{
while(q!=NULL&&q->next!=NULL)
{
q->data=q->data-8;
q->next->data++;
q=q->next;
}
if(q->data>=8)
{
q->data=q->data-8;
node* a=NULL;
a=new node;
a->next=NULL;
a->data=1;
q->next=a;
}
}
}
else if(p->data>=8)
{
while(p!=NULL&&p->next!=NULL)
{
p->data=p->data-8;
p->next->data++;
p=p->next;
}
if(p->data>=8)
{
p->data=p->data-8;
node* r=NULL;
r=new node;
r->next=NULL;
r->data=1;
p->next=r;
}
}
}
void reverseList(node* &first) //不带头结点的逆置方法
{
node* p=first;
node* q=NULL;
while(p!=NULL)
{
first=first->next;
p->next=q;
q=p;
p=first;
}
first=q;
}
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.双循环链表是否对称
判断带头结点的双循环链表是否对称
#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* p=first;
node* q=first;
if(first->next->data==first->prior->data)
{
p=first->next;
q=first->prior;
while(p!=q && p->next->data==q->prior->data)
{
p=p->next;
q=q->prior;
}
if(p==q) return 1;
else return 0;
}
else return 0;
}
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;
}