线性表的简单复习

一、链表

  1.顺序表的基本操作

(1).初始化(构造一个空的顺序表)

Status InitList(SqList &L)
{
L.elem=new ElemType[MAXSIZE];//为顺序表分配一个大小为MAXSIZE的数组空间
if(!L.elem)
exit(OVERFLOW);
L.length=0;
return OK;
}

(2).取值

【算法步骤】

1.判断指定的位置序号i值是否合理(1<=i<=L.length),若不合理,则返回ERROR。

2.若i值合理,则将第i个数据元素L.elem[i-1]赋给参数e,通过e返回第i个数据元素的传值

Status GetElem(SqList L,int i,ElemType &e)
{
if(i<1||i>L.length)
{return ERROR;}
e=L.elem[i-1];
return OK;
}

(3).查找

int LocateElem(SqList L,ELemType e)
{
for(i=0;i<L.length;i++)
{
if(L.elem[i]==e)
{return i+1;}
}
return 0;
}

(4).插入

【算法步骤】

1.判断插入位置是否合理,若不合理则返回ERROR

2.判断顺序表的存储空间是否已满,若满则返回ERROR

3.将第n个至第i个位置的元素依次向后移动一个位置,空出第i个位置(i=n+1时无需移动)

4.将要插入的新元素e放入第i个位置

5.表长加一

Status Listinsert(SqList &L,int i,ElemType e)
{
if((i<1)||(i>L.length+1))
{return ERROR;}
if(L.length==MAXSIZE)
{return ERROR;}
for(j=L.length-1;j>i;j--)
{
L.elem[j+1]=L.elem[j];
}
L.elem[i-1]=e;
L.length++:
return OK;
}

(5).删除

Status ListDelete(SqList &L,int i)
{
if((i<1)||(i>L.length))
{return ERROR;}
for(j=i;j<=L.length-1;j++)
{
L.elem[j-1]=L.elem[j];
}
--L.length;
return OK;
}

2.单链表(线性链表)

 单链表的存储结构

typedef struct node
{
ElemType data;//结点的数据域
struct node *next;//结点的指针域
}node,*LinkList;//LinkList为指向结构体node的指针类型

单链表的基本操作

(1).初始化

【算法步骤】

1.生成新结点为头结点,用头指针L指向头结点

2.头结点的指针域置空

Status InitList(LinkList &L)
{
L=new node;
L->next=NULL;
return OK;
}

2.取值

Status GetElem(LinkList L,int i,ElemType &e)
{//在带头结点的单链表L中根据序号i获取元素的值,用e返回L中第i个数据元素的值
p=L->next;
j=1;
while(p&&j<i)
{
p=p->next;
++j;
}
if(!p||j>i)
return ERROR;
e=p->data;
return OK;

}

3.查找

【算法步骤】
①用指针p指向首元结点。
②从首元结点开始依次顺着链域next向下查找,只要指向当前结点的指针p不为空,并且p所指结点的数据域不等于给定值e,则循环执行以下操作: p指向下-个结点。
③返回p。若查找成功,p此时指向结点的地址值,若查找失败,则p的值为NULL。

node *LocateElem(LinkList L,ElemType e)
{
p=L->next;//初始化
while(p&&p->data!=e)
{
p=p->next;
}
return p;
}

4.插入

【算法步骤】

将值为e的新结点插入表的第i个结点的位置,即插入结点ai-1与ai之间,如图所示:


 

 1.查找结点ai-1并由指针p指向该结点

2.生成一个新结点*s

3.将新结点*s的数据域置为e

4.将新结点*s的指针域指向结点ai

5.将结点*p的指针域指向新结点*s

【算法描述】

Status ListInsert(LinkList &L,int i,ElemType e)
{
p=L;j=0;
while(p&&(j<i-1))//查找第i-1个结点,p指向该结点
{p=p->next;j++;}
if(!p||j>i-1)
{return ERROR;}
s=new node;
s->data=e;//将结点*s的数据域置为e
s->next=p->next;//将结点*s的指针域指向ai
p->next=s;//将结点*p的指针域指向结点*s
return OK;

}

5.删除

Status ListDelete(LinkList &L,int i)
{
p=L;j=0;
while((p->next)&&(j<i-1))
{p=p->next;++j;}
if(!(p->next)||(j<i-1))
return ERROR;
q=p->next;//临时保存被删除结点的地址以备释放
p->next=q->next;//改变删除结点前驱结点的指针域
delete q;
return OK;
}

6.创建单链表

(1)前插法

void createList_H(LinkList &L,int n)
{
L=new node;
L->next=NULL;
for(i=0;i<n;i++)
{p=new node;
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
}

(2).后插法

void createList_R(LinkList &L,int n)
{
L=new node;
L->next=NULL;
r=L;
for(i=0;i<n;i++)
{p=new node;
scanf("%d",&p->data);
p->next=NULL;r->next=p;//将新结点*p插入尾结点*r之后
r=p;//r指向新的尾结点*p;
}
}

以上讨论的链式存储结构的结点中只有-个指示直接后继的指针域,由此,从某个结点出发只能顺指针向后寻查其他结点。若要寻查结点的直接前驱,则必须从表头指针出发。换句话说,在单链表中,查找直接后继的执行时间为O(1),而查找直接前驱的执行时间为O(n)。为克服单链表这种单向性的缺点,可利用双向链表。
顾名思义,在双向链表的结点中有两个指针域,一个指向直接后继,另一个指向直接前驱。

存储结构

typedef struct DULnode
{
ELemType data;
struct DuLnode *prior;
struct DuLnode *next;
}DuLnode,*DULinkList;

插入

Status ListInsert_DuL(DULinkList &L,int i,ELemType e)
{
if(!(p=GetElem_DUL(L,i))
return ERROR;
s=new DuLnode;
s->data=e;
s->prior=p->prior;
p->prior->next=s;
s->next=p;
p->prior=s;
return OK;
}

删除

Status ListDelete_DUL(DuLinkList &L,int i)
{
if(!(p=GetElem_DUL(L,i)))
return ERROR;
p->prior->next=p->next;//修改被删除结点的前驱结点的后继指针
p->next->prior=p->prior;//修改被删结点的后继结点的前驱指针
delete p;
return OK;
}

因为比较喜欢写专题,别的今天学的就不写在博客上了
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值