线性表的链式存储实现
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指向的是第i个结点
}
return j;
}
- 查找
- 按序号查找: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; //否则返回空
}
- 按值查找:Find
List FindKth(ElementType X,,List PtrL){
List p=Ptrl;
int i=1;
while(p!=NULL&&p->Data!=X)
P=P->Next;
return p;
}
- 插入(在第
i−1(1<=i<=n+1)个结点后插入一个值为X的新元素
)
- 先构造一个新节点,用s指向;
- 再找到链表的第i-1个结点,用p指向;
- 然后修改指针,插入结点(p之后插入新节点是s)
void 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); //查找第i-1个结点
if(p==NULL){ //第i-1个结点不存在,不能插入
printf("参数i错");
return NULL;
}
else{
s=(List)malloc(sizeof(struct LNode)); //申请、填装节点
s->Data=X;
s->Next=p->Next; //新节点插入在第i-1个结点的后面
p->Next=s;
return PtrL;
}
}
平均时间复杂度:1/2n
- 删除(删除表的第
i(1<=i<=n)
个位置上的元素)
- 先找到链表的第i-1个结点,用p指向
- 再用指针s指向要被删除的结点(p的下一节点);
- 然后修改指针,删除s所指结点;
- 最后释放s所指结点空间。
void 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;
return NULL;
}else if(p->Next==NULL){
printf("第%d个结点不存在",i); return NULL;
}else{
s=p->Next;
p->Next=s->Next;
free(s);
return PtrL;
}
}
平均时间复杂度:1/2n
广义表
【例】二元多项式:
P(x,y)=9x12y2+4x12+15x8y3−x8y+3x2
【分析】将二院多项式看成关于x的一元多项式
P(x,y)=(9y2+4)x12+(15y3−y)x8+3x2
广义表
- 广义表是线性表的推广
- 对于线性表而言,n个元素都是基本的单元素
- 广义表中,这些元素不仅可以是单元素也可以是另一个广义表。
typedef struct GNode GList;
struct GNode{
int Tag; //标志域:0表示结点是单元素,1表示结点是广义表
union{ //子表指针域SubList与单元素数据域data复用,即公用存储空间
ElementType Data;
GList SubList;
}URegion;
Glist Next; //指向后继结点
};
多重链表
多重链表:链表中的结点可能同时隶属于多个链
- 多重链表中结点的指针域会有多个
- 但包含两个指针域的链表并不一定是多重链表,比如双向链表
多重链表的用途:基本如树、图这样相对复杂的数据结构都可以采用多重链表方式实现存储。
【例】矩阵可以用二维数组表示,但有缺陷:
- 一是数组的大小需要事先确定
- 对于“稀疏矩阵”,将造成大量存储空间浪费
【分析】采用一种经典的多重链表——十字链表来存储稀疏矩阵
- 只存储军阵非0元素项
结点的数据域:行坐标Row 列坐标Col 数值Value
- 每个结点通过两个指针域,把同行、同列串起来;
- 行指针(或称为向右指针)Right
- 列指针(或称为向下指针)Down
矩阵A的多重链表图
- 用一个标志域Tag来区分结点和非0元素结点
- 头结点的标识值为“Head”,矩阵非0元素结点的标识值为“Term”