一.线性表
线性表(Linear List):由同类型数据元素构成有序序列的线性结构
- 表中元素个数称为线性表的长度
- 线性表没有元素时,称为空表
- 表的始位置称表头,表的结束位置称表尾
2.线性表的抽象数据类型描述
- 类型名称:线性表(List)
- 数据对象集:线性表是 个元素构成的有序序列
- 操作集:线性表l List,整数i表示位置,元素XElementType,
- 线性表基本操作有:
- 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;
3.线性表的顺序存储实现
typedef struct LNode *List;
struct LNode{
ElementType Data[MAXSIZE];
int Last;
};
struct LNode L;
List PtrL;
所以:
- 访问下标为i的元素:L.Date[i] 或 Ptrl->Date[i]
- 线性表的长度:L.List+1 或 Ptrl->List+1
4.主要操作的实现:
- 初始化(建立新的顺序表)
List MakeEmpty()
{
List PtrL;
PtrL = (List )malloc( sizeof(struct LNode)); //申请结构的内存
PtrL->Last = -1; Last指向最后一个元素
return PtrL;
- 查找
int Find( ElementType X, List PtrL)
{
int i=0;
while(i <= PtrL->Last && PtrL->Data[i]!=X)
i++;
if(i>PtrL->Last) return -1; //如果没有找到,返回-1
else return i; //找到后返回的是储存的位置
}
- 插入(第i(1<=i<=n+1)个位置上插入一个值为X的新元素)
void Insert( ElementType X ,int i,List PtrL)
{
int j;
if(PtrL->Last == MAXSIZE-1){ //检查表是否已满
printf("表满");
return;
}
if(i<1||i>PtrL->Last+2){ //检查位置是否合适
printf("位置不合法");
return;
}
for(j=PtrL->Last;j>=i-1;j--)
PtrL->Data[j+1]=PtrL->Data[j]; //将a1~an倒序向后移动
PtrL->Data[i-1]=X; //插入新元素
PtrL->Last++; //Last仍然指向最后元素
return;
}
- 删除(第i(1<=i<=n+1)个位置上的元素)
void Delete(int i,List PtrL)
{ int j;
if(i<i||i>PtrL->Last+1){ //检查空表和删除位置是否合法
printf("不存在第%d个元素",i);
return ;
}
for(j=1;j<=PtrL->Last;j++)
PtrL->Data[j-1]=PtrL->Data[j]; //将a(i+1)~an顺序向前移动
PtrL->Last--; //Last仍指向最后元素
return;
}
4.线性表的链式存储实现
-
不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。
-
插入,删除不需要移动数据元素,只需要修改“链”。
typedef struct LNode *List;
struct LNode{
ElementType Data; //这个节点的数据
List Next; //下一个节点的位置
};
struct Lnode L;
List PtrL;
- 求表长
int Length(List PtrL) //遍历整个链表
{ List p=PtrL; //P指向表的第一个节点
int j=0;
while(p){
p=p->Next;
j++; //当前p指向的是第j个节点
}
return j;
}
- 查找
1.按序号查找: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; //否则返回空
}
2.按值查找
List Find(ElementType X,List PtrL)
{
List p= PtrL;
while(p!=NULL && p->Data!=X)
p=p->Next;
return p;
}
- 插入(第i(1<=i<=n+1)个节点后插入一个值为X的新节点)
1.先构造一个新的节点,用s指向;
2.再找到链表的第i-1个节点,用p指向;
3.然后修改指针,插入节点(p之后插入新的节点是s);
List Insert(ElementType X,int i,List PtrL)
{ List p,s;
if(i==1){ //新节点在表头
s=(List)malloc(sizeof(struct LNode)); //(1)申请新节点内存,填装节点
s->Data=X;
s->Next=PtrL;
return s; //返回新表头指针
}
p=FindKth(i-1,PtrL); //查找第i-1个节点
if(p==NULL){ //不能插入
printf("参数i错误");
return NULL;
}else{
s=(List)malloc(sizeof(struct LNode)); //(1)
s->Data=X;
s->Data=p->Data; //新节点插在i-1个节点后面
p->Data=PtrL;
return PtrL;
}
- 删除(第i(1<=i<=n+1)个位置上的节点)
1.先找到链表的第i-1个节点,用p指向;
2.再用指针s指向要被删除的节点;
3.然后修改指针,删除s所指节点;
4.释放s所指节点的空间;
List Delete(int i;List PtrL)
{ List p,s;
if(i==1){
s=PtrL;
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;
p->Next=s->Next;
free(s);
return PtrL;
}