什么是线性表
线性表:有同类型数据元素构成有序序列的线性结构
表中元素个数称为线性表的长度
线性表没有元素时,称为空表
表起始位置称为表头,表结束位置称为表尾
线性表的抽象数据类型描述:
类型名称:线性表
数据对象集:线性表是n(>=0)个元素构成的有序序列(a1,a2.......)
操作集:线性表L属于List,整数i表示位置,元素X属于ElementType,线性表基本操作主要有:
1、List MakeEmpty():初始化一个空线性表L;
2、ElementType FindKth(int K,List L):根据位序K。返回相应元素;
3、int Find(ElementType X,List L):在线性表L中查找X的第一次出现的位置;
4、void Insert(ElementType X,int i,List L):在位序i前插入一个新元素X;
5、void Delete(int i,List L):删除指定位序i的元素;
6、int Length(List L):返回线性表L的长度n。
一、线性表的顺序存储实现(数组)
首先创建结构体:
//创建结构体
typedef struct LNide *List;
struct LNode{
ElementType Data[MAXSIZE];//MAXSIZE是define设定的常数
int Last;
};
struct LNode L;
List Ptrl;
//访问下标为i的元素:L.Data[i]或PtrL->Data[i]
//线性表的长度为L.Last+1或PtrL->Last
主要操作的实现
1、初始化(建立空的顺序表)
List MakeEmpty()
{
List PtrL;
PtrL = (List)malloc(sizeofz(struct LNode));
Ptrl->Last = -1;
return Ptrl;
}
2、查找
int Find(ElementTyoe,List PtrL)
{
int i = 0;
while(i <= PtrL->Last && PtrL->Data[i] != X)
i++;
if(i > Ptrl->Last) return -1;
else return i;
}
//如果没有找到返回-1,如果找到了返回的是存储的位置,即存储元素的下标。
//查找成功的平均次数为(n+1)/2,平均时间性能为0(n)
3、插入操作实现
void Insert(ElementType X,int i,List PtrL)
{
int j;
if(PtrL->Last == MAXSIZE - 1){ //空间已满,不能插入
printf("表满");
return;
}
if(i < 1 || Ptrl->Last + 2){
printf("位置不合法");
return;
}
for(j =PtrL->Last;j>=i-1;i++) //将插入元素后面的向后移动,新元素插入,Last仍指向最后元素
PtrL->Data[j+1] = PtrL->Data[j];
Ptrl->Data[i-1] = X;
PtrL->Last++;
return;
}
4、删除操作实现
void Delete(int i,Last PtrL)
{
int j;
if(i < 1 || i > Ptrl->Last + 1){
printf("不存在第%d个元素");
return;
}
for(j = i;j <= PtrL->Last,j++)
Ptrl->Data[j-1] = PtrL->Data[j];
PtrL->Last--;
return;
}
//将第i个元素后的数据迁移一位,Last仍指向最后元素
二、线性表的顺序存储实现(链表)
1、创建结构体
typedef struct LNode *List;
struct LNode{
ElementTyoe Data;
List Next;
};
struct Lnode L;
List PtrL;
2、初始化
List MakeEmpty()
{
List PtrL;
PtrL = (List)malloc(sizeofz(struct LNode));
return Ptrl;
}
3、求表长
int Length(List PtrL)
{
List p = PtrL; //p指向表的第一个结点
int j = 0;
while(p){
p = p->Next;
j++; //当前p指向的是第j个结点
}
return j;
}
4、查找
按序号查找:FindKth;
List FindKth(int K,List Ptrl)
{
List p = PtrL;
int i = 1;
while(p != NULL && i < k){
p = p->Next;
i++;
}
if(i == K) return p; //找到第K个,返回指针
else return NULL; //否则返回NULL
按值查找:Find
List Find(ElementType X,List PtrL)
{
List p = PtrL;
while(p != NULL && p->Data != X)
p = p->Next;
return p;
}
5、插入
先构造一个新节点,用s指向;
再找到链表的第i-1个结点,用p指向;
然后修改指针,插入节点(p之后插入新节点是s)
代码如下:
List Insert(ElementType X,int i,List PtrL)
{
List p,s;
if(i == 1){ //新节点插入在表头,,申请、填装结点
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = PtrL;
return s;
}
p = FindKth(i-1,PtrL);
if(p == NULL){
printf("参数i错误");
return NULL;
}else{
s = (List)malloc(sizeof(struct LNode));
s->Data = X;
s->Next = p->Next;
p->Next = s;
return PtrL;
}
6 、删除
先找到链表的第i-1个结点,用p指向;
再用指针s指向要被删除的结点;
然后修改指针,删除s所指向结点;
最后释放s所指向结点的空间。
代码如下:
List Delete(int i,List PtrL)
{
List p,s;
if(i == 1){ //若要删除的是表的第一个结点
s = PtrL; //s指向第一个结点
if(Ptrl != NULL) PtrL = PtrL->Next; //从链表中删除
else return NULL;
free(s);
return PtrL;
}
p = FindKth(i-1,PtrL);
if(p == NULL){
printf("第%d个结点不存在",i-1);
return NULL;
}else if(p->Next == NULL){
printf("第%d个结点不存在",i);
return NULL;
}else {
s = p->Next; //s指向第i个结点
p->Next = s->Next; //从链表删除
free(s); //释放被删除结点
return PtrL;
}
}