一.简单介绍
线性表是一种典型的数据结构, 线性结构的基本特点是线性表中的数据元素是有序且有限的, 在线性结构中, 有且仅有一个被称为"开始数据元素"和一个"最后数据元素", 除了开始数据元素没有直接前驱, 最后一个数据元素没有直接后继外, 其余的数据元素有且仅有唯一的一个直接前驱和直接后继。对线性表比较详细的介绍。https://www.cnblogs.com/mr-wid/archive/2012/12/07/2807817.html
整理下来说, 线性表具有如下基本特征:
1.线性结构中必然存在唯一一个"开始数据元素" ;
2.线性结构中必然存在唯一一个"最后数据元素" ;3.除第一个数据元素外, 其他元素均有唯一一个直接前驱 ;
4.除最后一个数据元素外, 其他元素均有唯一一个直接后继 。
二.基本运算
(一)数组实现
1.线性表的结构体:
typedef int position;
typedef int Elementype;
struct LIST{
Elementype elements[maxlength];
int last;
};
2.返回最后一个元素下标:
position End(LIST L){
return(L.last+1);
}
3.插入操作:
//把x插入到表L中的位置p处
void Insert(Elementype x,position p,LIST &L){
position q;
if(L.last >= maxlength-1)
cout<<"list is full"<<endl;
else if((p >L.last+1) ||(p < 1)){
cout<<"position does not exist"<<endl;
}
else{
for(q = L.last;q >= p;q--){
L.elements[q+1] = L.elements[q];
}
L.last = L.last + 1;
L.elements[p] = x;
}
}
4.删除操作:
//删除L中位置p中的元素
void Delete(position p,LIST &L){
position q;
if((p >L.last) || (p < 1)){
cout<<"position does not exist"<<endl;
}
else{
L.last = L.last-1;
for(q = p;q <= L.last;q++){
L.elements[q] = L.elements[q+1];
}
}
}
5.返回表L中x的位置
//返回表L中x的位置
position Locate(Elementype x,LIST L){
position q;
for(q = 1;q <= L.last;q++){
if(L.elements[q] == x){
return q;
}
}
return L.last+1;
}
6.合并两个表L1,L2
void merge(LIST&L,LIST&L1,LIST&L2) {
position p=0,p1,p2;
position len1=End(L1);
position len2=End(L2);
for(p1=0;p1<End(L1);p1++)
{ L.elements[p]=L1.elements[p1]; p++; }
p--;
for(p2=0;p2<End(L2);p2++)
{ L.elements[p]=L2.elements[p2]; p++; }
p--;
L.last = p;
}
(二)指针实现
1.线性表的结构体
typedef int Elementype;
struct celltype{
Elementype element;
celltype *next;
};
typedef celltype *position;
typedef celltype *LIST;
2.返回线性表L中指向最后一个节点的指针
position End(LIST L){
position p;
p = L;
while(p->next!=NULL){
p = p->next;
}
return p;
}
3.插入操作
void Insert(Elementype x,position p){
position q;
q = new celltype;
q->element = x;
q->next = p->next;
p->next = q;
}
4.删除操作
void Delete(position p){
position q;
if(p->next != NULL){
q = p->next;
p->next = q->next;
delete q;
}
}
5.返回L中指向x的指针:
position Locate(Elementype x,LIST L){
position p;
p = L;
while(p->next!=NULL){
if(p->next->element == x){
return p;
}
else
p = p->next;
}
return p;
}
6.置空表
position MakeNull(LIST &L){
L = new celltype;
L->next = NULL;
return L;
}
7.合并两个表
void merge(LIST &L,LIST &L1,LIST &L2){
position p,p1,p2;
for(p1 = L1;p1;p1 = p1->next){
p = new celltype;
p->element = p1->element;
if(L == 0){
L = p;
p2 = p;
}
else{
p2->next = p;
p2 = p;
}
}
p2->next = NULL;
for(p1 = L2;p1;p1= p1->next){
p = new celltype;
p->element = p1->element;
if(L == 0){
L = p;
p2 = p;
}
else{
p2->next = p;
p2 = p;
}
}
p2->next = NULL;
}
8.复制链表
void Copy(LIST &L,LIST &L1){
position p,p1,p2;
for(p1 = L1;p1;p1 = p1->next){
p = new celltype;
p->element = p1->element;
if(L == 0){
L = p;
p2 = p;
}
else{
p2->next = p;
p2 = p;
}
}
p2->next = NULL;
}
三.实例
1.已知一个单向链表,试给出复制该链表的算法。
要求:1、定义线性表的节点的结构以及节点的型和位置的型。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。
4、在main函数中进行测试:先构建一个线性表,并定义一个空线性表,然后进行复制。
#include<iostream>
using namespace std;
#include<iomanip>
#include<vector>
#include<algorithm>
typedef int Elementype;
struct celltype{
Elementype element;
celltype *next;
};
typedef celltype *position;
typedef celltype *LIST;
position End(LIST L){
position p;
p = L;
while(p->next!=NULL){
p = p->next;
}
return p;
}
void Insert(Elementype x,position p){
position q;
q = new celltype;
q->element = x;
q->next = p->next;
p->next = q;
}
void Delete(position p){
position q;
if(p->next != NULL){
q = p->next;
p->next = q->next;
delete q;
}
}
position Locate(Elementype x,LIST L){
position p;
p = L;
while(p->next!=NULL){
if(p->next->element == x){
return p;
}
else
p = p->next;
}
return p;
}
position MakeNull(LIST &L){
L = new celltype;
L->next = NULL;
return L;
}
void Copy(LIST &L,LIST &L1){
position p,p1,p2;
for(p1 = L1;p1;p1 = p1->next){
p = new celltype;
p->element = p1->element;
if(L == 0){
L = p;
p2 = p;
}
else{
p2->next = p;
p2 = p;
}
}
p2->next = NULL;
}
void Read(LIST &L){
position p1,p2;
cout<<"输入-1以结束."<<endl;
while(1){
p1 = new celltype;
cin>>p1->element;
if(p1->element == -1){
break;
}
if(L == 0){
L = p1;
p2 = p1;
}else{
p2->next = p1;
p2 = p1;
}
}
p2->next = NULL;
}
void print(LIST &L){
position p;
p = L;
for(;p;p = p->next){
cout<<p->element<<'\t';
}
cout<<endl;
}
int main(){
LIST L = NULL,L1 = NULL,L2 = NULL;
Read(L1);
print(L1);
Copy(L,L1);
print(L);
return 0;
}
2.写出从一个带表头的单链表中删除其值等于给定值x的结点的算法函数:
int Delete(LIST &L, int x);如果x在该链表中,则删除对应结点,并返回其在链表中的位置(逻辑位置,第一个结点的逻辑位置为1),否则返回-1。
要求:1、定义线性表的节点的结构以及节点的型和位置的型。
2、定义线性表的基本操作
3、在1,2的基础上,完成本题。
4、在main函数中进行测试:先构建一个线性表,然后调用函数删除值等于给定值的节点。
#include<iostream>
using namespace std;
#include<iomanip>
#include<vector>
#include<algorithm>
typedef int Elementype;
struct celltype{
Elementype element;
celltype *next;
};
typedef celltype *position;
typedef celltype *LIST;
position End(LIST L){
position p;
p = L;
while(p->next!=NULL){
p = p->next;
}
return p;
}
void Insert(Elementype x,position p){
position q;
q = new celltype;
q->element = x;
q->next = p->next;
p->next = q;
}
void Delete(position p){
position q;
if(p->next != NULL){
q = p->next;
p->next = q->next;
delete q;
}
}
position Locate(Elementype x,LIST L){
position p;
p = L;
while(p->next!=NULL){
if(p->next->element == x){
return p;
}
else
p = p->next;
}
return p;
}
position MakeNull(LIST &L){
L = new celltype;
L->next = NULL;
return L;
}
int Delete1(LIST &L,int x){
position p = L;
int cnt = 0;
while(p->next !=NULL){
// cnt++;
if(p->next->element == x){
if(p->next->next!=NULL){
position q;
q = p->next;
p->next = q->next;
delete q;
}
else{
delete p->next;
p->next = NULL;
}
cnt++;
}
else{
p = p->next;
}
}
return cnt;
}
void Read(LIST &L){
position p1,p2;
cout<<"输入-1以结束."<<endl;
while(1){
p1 = new celltype;
cin>>p1->element;
if(p1->element == -1){
break;
}
if(L == 0){
L = p1;
p2 = p1;
}else{
p2->next = p1;
p2 = p1;
}
}
p2->next = NULL;
}
void print(LIST &L){
position p;
p = L;
for(;p;p = p->next){
cout<<p->element<<'\t';
}
cout<<endl;
}
int main(){
LIST L = NULL,L1 = NULL;
Read(L);
print(L);
Delete1(L,4);
print(L);
return 0;
}
这一个代码有一丢丢的小问题,就是第一个字母为删除的元素时,不会删除,尝试了几次发现越改越遭,先放一放,之后再改一下。