List
线性表存储及相关操作
线性表是由同类型数据元素构成有序序列的线性结构
- 顺序存储
struct LNode
{
ElemType Data[MAXSIZE]; /*ElemType 可以是预先定义的struct类型*/
int last; /*指示最后一个元素的下标*/
};
typedef struct LNode *List; /*指向结构的指针*/
struct LNode L;
List PtrL;
初始化
List MakeEmpty()
{
List PtrL;
PtrL=(List)malloc(sizeof(struct LNode));
PtrL->last=-1;
return PtrL;
}
查找
int Find(List PtrL,ElemType X)
{
int i=0;
while(i<= PtrL ->last&&PtrL->Data[i]!=X) i++; /*结构体可以整体比较和赋值*/
if(i>PtrL->last) return -1;
else return i;
}
插入
void Insert(List Ptrl, ElemType x,int i)
{
if(PtrL->last=MAXSIZE-1)
printf("表满“);
else if(i<1||i>last+2)
printf("位置不合法“);
else
{
for(int j=Ptrl->last;j>=i-1;j--)
PtrL->Data[j+1]=PtrL->Data[j];
PtrL->Data[i-1]=X;
PtrL->last++;
}
}
删除
void Delete(List PtrL,int i)
{
if(i<1||i>PtrL->last+1)
printf("不存在第%d个元素”,i);
for(int j=i;j<=PtrL ->last;j++)
{
PtrL->Data[j-1]=PtrL->Data[j];
}
ptrL->last--;
}
- 链式存储
struct LNode
{
ElemType data; /*ElemType可以是预先定义的struct类型*/
struct LNode *next; /*下一个结点的位置,如为NULL则表示到了末尾*/
};
typedef struct LNode *List; /*指向结构的指针*/
struct LNode L;
List PtrL;
初始化(头结点视为第0个结点)
List MakeEmpty()
{
List PtrL;
PtrL=(List)malloc(sizeof(struct LNode));
PtrL->next=null;
return PtrL;
}
求表长
int Length(List PtrL) /*PtrL为头指针,指向第一个结点(假设无头结点)*/
{
List p=PtrL;
int j=0;
while(p)
{
p=p->next;
j++;
}
return j;
}
查找(分为按序号和按值查找)
List(int k, List PtrL) /*头指针原本即指向第一个结点的地址*/
{
List p=Ptrl;
int i=1;
for(p!=null&&i<k)
{
p=p->next; /* p是指针即地址,而不是下一个结点的next值 */
i++;
}
if(i==k) return p;
else return null;
}
插入
List Insert( List PtrL, ElementType X, int i) /*无头结点则要判断是否为插入第一个结点*/
{
List p,s; /*p表示插入点前一个结点,s表示插入的结点*/
if(i= =1)
{
s=(list)malloc(sizeof(struct LNode));
s->data=X;
s->next=PtrL;
return s;
}
else
{
p=Find(i-1,PtrL);
if ( p==NULL )
printf("插入位置参数错误\n");
else
{
s = (list)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
s->Data = X;
s->Next = p->next;
p->Next = s;
return PtrL;
}
}
}
删除
List Delete( List PtrL,int i)
{
List p,s;
if(i= =1)
{
s=PtrL;
if(PtrL) PtrL=PtrL->next;
else return NUll;
free(s);
return PtrL;
}
else
{
p=Find(i-1,PtrL);
if(p||p->next) printf("第%d个结点不存在,i);
else
{
s=p->next;
p->next=s->next;
free(s);
return PtrL;
}
}
}
建表
链表和顺序表不同,它是一种动态结构,整个可用存储空间可为多个链表共同享用,每个链表占用的空间不需预先分配划定,而是由系统按需即时生,因此,建立线性表的链式存储结构的过程就是一个动态生成链表的过程。因此,从空表的初始状态起,依次建立各元素结点,并逐个插入链表
List CreateList(int n)
{
List PtrL=(list)malloc(sizeof(struct LNode));
scanf("%d",&PtrL->data);
PtrL->next=null;
for(int i=0;i<n;i++)
{
List p=(list)malloc(sizeof(struct LNode));
scanf("%d",&p->data);
p->next=PtrL->next;
PtrL->next=p;
}
return PtrL;
}
线性表应用
- 有序表的合并
顺序有序表
①创建一个表长为 m+n 的空表 LC
②指针 pc 初始化,指向 LC 的第一个元素
③指针 pa , pb 初始化,分别指向 LA 和 LB 的第一个元素
④当指针 pa , pb 均为到达相应的表尾时,则依次比较 pa , pb 所指向的元素值,从 LA ,LB 中摘取值更小的那个元素插入 LC 的末尾
⑤如果 pa 已到达表 LA 的末尾,则依次将 LB 的剩余元素插入 LC 的末尾
⑥如果 pb 已到达表 LB 的末尾,则依次将 LA 的剩余元素插入 LC 的末尾
void MergeList(List LA , List LB , List LC)
{
LC.length=LA.length+LB.length; /*可以用线性表结构的last表示*/
LC.data=(ElemType*)malloc(LC.lenth * sizeof(ElemType)); /*ElemType为类型说明*/
ElemType *pa,*pb,*pc;
pa=LA->data; pb=LB->data; pc=LC->data;
int i,j;
for(i=1,j=1;i<=LA.length&&j<=LB.length;)
{
if(*pa<=*pb)
{
*pc++ = *pa++; i++;
}
else
{
*pc++ = *pb++; j++;
}
}
while(i++ <= LA.length) *pc++ = *pa++;
while(j++ <= LB.length) *pc++ = *pb++;
}
- 链式有序表
②LC 的头结点取 LA 的头结点
③指针 pc 初始化,指向 LC 的头结点
④当指针 pa 、pb 均为到达相应的表尾时,则依次比较 pa ,、pb 所指向的元素值,从 LA 、LB 中摘取元素值更小的那个结点插入 LC 的末尾
⑤将非空链表的剩余段插入到 pc 所指结点之后
⑥释放 LB 的头结点
void MergeList(List LA , List LB , List LC)
{
List LC=LA;
List pa,pb,pc;
pa=LA->next; pb=LB->next;
pc=LC
while(pa&&pb) /*LA 和 LB 均未达到表尾*/
{
if(pa->data<=pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
pc->next=pa?pa:pb; /*链接剩余段*/
free(LB);
}
- 多项式的运算
多项式的表示
typedef struct PNode
{
float coef; /*系数*/
int expn; /*指数*/
struct PNode *next;
}
typedef struct PNode *Polynomial; /*指向结构的指针*/
多项式的创建(建表过程中需要保证多项式链表是个有序表)
①创建一个只有头结点的空链表
②根据多项式的项的个数n,循环n次执行以下操作
- 生成一个新结点 *s
- 输入多项式当前项的系数和指数赋给新节点 *s 的数据域
- 设置前驱指针 former 循链找到并指向要插入项的前驱结点,初值指向头结点
- 设置后继指针 latter 循链指向并指向要插入项的后继结点,初值指向首元结点
- 将结点插入前驱、后继结点之间
Polynomial P=(Polynomial)malloc(sizeof(struct PNode));
p->next=NULL;
void CreatePoly(Polynomial P,int n)
{
Polynomial s
for(int i=1;i<=n;i++)
{
s = (Polynomial)malloc(sizeof(struct PNode));
cin>>s->coef>>s->expn;
former = P; latter = P->next;
while(latter&&latter->expn < s->next)
{
former=latter;
latter=latter->next;
}
s->next=latter; former->next=s;
}
}
多项式相加
①指针 pa 和 pb 初始化,分别指向单链表 Pa 、Pb 的首元结点
②pc 指向结果多项式的当前结点,初值为 pa
③pa 和 pb 均未到达相应表尾时,则循环比较 pa、pb 所指结点对应的指数
- 若 pa->next = pb->next
将两个结点的系数相加,如果和不为零,则修改 pa 所指结点的系数值,同时删除 pb 所指结点,如果为零,则删除 pa、pb 所指结点
-若 pa->next < pb->next
将 pa 所指结点插入结果链表
-若 pa->next > pb->next
将 pb 所指结点插入结果链表
④将非空多项式的剩余段插入到 pc 所指结点之后
⑤释放 pb 的头结点
void AddPoly(Polynonial Pa,Polynomial Pb)
{
Polynonial pa,pb,pc;
pa=Pa->next; pb=Pb->next;
pc=Pa;
while(pa&&pb)
{
if(pa->expn==pb->expn)
{
float sum=pa->coef + pb->coef;
if(sum!=0)
{
pa->coef = sum;
pc->next=pa; pc=pa; pa=pa->next;
Polynonial delete=pb; /*释放pb结点*/
pb=pb->next;
free(pb);
}
else
{
Polynonial delete=pa; /*释放pa和pb结点*/
pa=pa->next;
free(pa);
delete=pb;
pb=pb->next;
free(pb);
}
}
else if(pa->expn<pb->expn)
{
pc->next=pa; pc=pa; pa=pa->next;
}
else
{
pc->next=pb; pc=pb; pb=pb->next;
}
}
pc->next=pa?pa:pb; /*链接剩余段*/
free(Pb);
}