2.线性表的链式存储实现
不要求逻辑上相邻的两个元素物理上也相邻;通过“链”建立起数据元素之间的逻辑关系。
插入、删除不需要移动的数据元素,只需修改“链”。
(1)求表长
用链表遍历的方法
int Length (List PtrL)
{
List p=PtrL;//p指向表头
int j=0;
while(p)
{
p=p->Next;//每循环一次指针向后挪一位,循环到最后一个结点p指向NULL
j++;
}
return j; //返回表长
}
(2)查找
按序号查找FindKth
List FindKth;
{
List p=PtrL;//p是一个临时指针、一个变量。让其指向表头
int i=1; //第几个元素
while(p!=NULL&&i<K)//表不空&&还未找到要找的东西
{
p=p->Next;
i++;
}
if(i==K) return p;//找到第K个,返回指针
else return NULL;//未找到
}
按值查找Find
List Find(ElementType X,Lidt PtrL)
{
List p=PtrL;
while(p!=NULL&&p->Data!=X)//表不空&&没有找到
p=p->Next;
return p;
}
(3)插入
把值为X的新结点插入第i-1(1<=i<=n+1)个结点之后
步骤: 先构造一个新结点,用s指向。再找到链表的第i-1个结点,用p指向。然后修改指针,插入结点。
List Insert(ElmentType X,int i,List PtrL)
{
List p,s;
if(i==1) //插入位置位于表头,没有i-1
{
s=(list)malloc(sizeof(struct LNode));//申请空间
s->Data=X;//s的Data值设为X
s->Next=PtrL;
return s;//返回新表头指针
}
p=FindKth(i-1,PtrL);//通过FindKth函数找到i-1这个结点的位置,并把此处指针赋给p
if(p==NULL) //i-1位置的结点不存在,不可以插入
{
printf("参数i错误");
return NULL;
}
else //正常情况,按步骤进行
{
s=(List)malloc(siaeof(struct LNode));
s->Data=X;
s->Next=p->Next;
p->Next=s;
return PtrL;
}
}
(4)删除
删除链表的第i(1<=i<=n)个位置上的结点
步骤:先找到链表的第i-1个结点,用p指向。再用指针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;
}
3.广义表
(1)广义表是线性表的推广
(2)对于线性表而言,n个元素都是基本的单元素
(3)广义表中,这些元素不仅可以是单元素也可以是另一个广义表
typedef struct GNode *GList;
struct GNode
{
int Tag;//标志域:0表示结点是单元素,1表示结点是广义表
union//union共用体,可以把不同数据类型的数据组合在一起。子表指针域Sublist与单元素数据域Data复用,即共用存储空间
{
ElementType Data;
GList SubList;
}URegion;
GList Next;//指向后继结点
};
*数据域与指针域
链表由一系列结点组成,结点可以在运行时动态生成。每个结点包括两个部分,一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
2.多重链表
(1)多重链表中的结点可能同时隶属于多个链。
(2)多重链表中结点的指针域会有多个,如上面例子包含了Next和Sublist两个指针域。
(3)包含两个指针域的链表并不一定是多重链表(双向链表不是多重链表)。
*双向链表
双向链表是链表的一种,它的每个数据结点都有两个指针,分别指向直接后继(结点的后一个结点)和直接前驱(结点的前一个结点)。
(4)用途:基本上像树,图这样相对复杂的数据结构都可以采用多重链表方式实现存储。