线性表
1定义
线性表(Linear List)”:由同类型数据元素构成有序序列的线性结构
2线性表的抽象数据类型描述
- 类型名称:线性表(List)
- 数据对象集:线性表是 n (≥0)个元素构成的有序序列( a1, a2, …,an )
- 操作集:线性表L ∈ \in ∈ List,整数i表示位置,元素X ∈ \in ∈ ElementType, 线性表基本操作主要有:
- List MakeEmpty():初始化一个空线性表L;
- ElementType FindKth( int K, List L ):根据位序K,返回相应元素 ;
- int Find( ElementType X, List L ):在线性表L中查找X的第一次出现位置;
- void Insert( ElementType X, int i, List L):在位序i前插入一个新元素X;
- void Delete( int i, List L ):删除指定位序i的元素;
- int Length( List L ):返回线性表L的长度n。
2.1 线性表的顺序储存
用一段连续的内存来储存线性表得各个元素,引入需要插入数据,所以就要申请足够大的空间。变量list来储存表中最后一个元素在数组种的位置,空表的时候list=-1;
顺寻存储的时候表用结构体表示:
typedef struct LNode *PtrToLNode;
struct LNode
{
ElementType Data[MAXSIZE];
Position Last;
}
当需要把表的结构体传给函数形参的时候,直接传结构体效率比较慢,所以采用指针的方法传递。
typedef ProToPLNode List;//List为指向结构体LNode的结构体变量
List L;//声明L变量,L是指向结构体LNode的
L->Data[1];//访问线性表的序号为1的元素。
L->Last+1;//访问线性表长度
2.1.1操作集实现-初始化
线性表的初始化
List MakeEmpty()
{
List PtrL;
PtrL=(List)malloc(sizeof(struct LNode));//开辟一个表的空间,结构体变量指向
PtrL->Last=-1;
return PtrL;//返回指向结构体LNode(表)的指针
}
2.1.2操作集实现-表中查找某元素
int Find(Elementtype x,List L);//L是指针变量
{
int i=0;//元素位置
while(i<L=->Last && L->Data[i]!=x)
i++;
if(i>L->Last)
return ERROR;//ERROR表示错误信息
return i;
}
时间复杂度为O(n);
2.1.3 操作集实现-在某位置插入某元素
bool Insert(List L,int i,ElementType x)//x可以是任何类型
{
int j;
if(L->Last==MAXSIZE-1)
{
printf("表已满");
return false;
}
if(i<1||i>L->Last+2)
{
printf("位置不合法");
return false;
}
for(j=L->Last;j>=i-1;j--)
{
L->Data[j+1]=L->Data[j];
}
L->Data[i-1]=x;
L->Last++;
return True;
}
复杂度O(n)
2.1.4 操作集实现-删除线性表中某次序的元素
bool Delete(List L,int i)
{
int j;
if(i<1||i>L->Last+1)
{
printf("位序%d不存在",i);
return false;
}
for(j=i+1;j<=L-Last;j++)
{
L->Data[i]=L->Last[i+1];
}
L->Last--;
return True;
}
复杂度O(n)
2.2 线性表的链式存储实现
链式表示的线性表与顺序储存略有不同,顺序存储时一个表定义为结构体。但是链表定义的时候定义每一个结点。表头指针指向链表的的第一个单元,并表示一个链表。结构体信息有元素值以及下一结点的地址
typedef struct LNode *ProToNode;
struct LNode
{
ElementType Data;
ProToNode Next;
};
typedef ProToNode List;//List是指针变量,我们在这里用它的作用就是指向链表的首结点(每个结点都是一个结构体,所以指针也是结构体指针),表示指向一个链表。
typedef ProToNode Podition;//这句并非是多余,我们是为了表示起来一目了然
2.2.1 操作集-求表长
定义移动指针p和计数器cut;
int Length(List L)
{
Position p;
int cnt=0;
p=L;//移动指针指向链表头
while(p)//只要不指向链尾就继续
{
p=p->Next;
cnt++;
}
return cnt;
}
操作集-查找某元素
按序号查找
#define ERROR -1;//一般定义表中元素不可能取到的值
ElementType FindKth(List L,int K)//按次序查找
{
position p;
int cnt=1;
p=L;
while(p&&cnt<k)
{
p=p->Next;
cnt++
}
if((cnt==k)&&p)
{
return p->Data;//找到第K个元素
}
else
return ERROR;
}
按值查找
Position Find(List L,elementtype x)//返回所查元素的地址
{
Position p;
p=L;
while(p->Data==x&&p)
p=p->Next;
return p;
}
复杂度为O(n)
操作集-插入
在指定位序前插入新元素X,
List Insert(List L,ElementType x,int i)//返回表头指针
{
Position per,tmp;
tmp=(Posiston)malloc(sizeof(struct LNode))
tmp->Data=x;
if(i==1)
{
tmp->Next=L;
return tmp;
}
else
{
int cnt=1;
pre=L;
while(pre &&cnt<i-1)
{
pre=pre->Next;
cnt++
}
if(pre==NULL&&cnt!=i-1)
{
printf("插入位置出错");
free(tmp);
return ERROR;
}
else
{
tmp->Next=pre->Next;
pre->Next=tmp;
return L;
}
}
}