学习 严蔚敏讲数据结构笔记05

150 篇文章 0 订阅
28 篇文章 0 订阅

04_006

Status ListInsert_L(LinkList L, int pos,  ElemType e)

{

         p  = L;

         j  = 0;

         while(p  && j < pos-1)

         {

                   p  = p->next;

                   ++j;  //寻找第pos-1个结点

                   if(!p  || j > pos-1)

                            return  ERROR; // pos小于1或者大雨表长

                   s  = (LinkList) malloc(sizeof(LNode)); //生成新结点

                   s->data  = e;

                   s->next  = p->next; //插入L

                   p->next  = s;

                   return  OK;

         }

} //LinstInsert_L

算法的时间复杂度为:O(ListLength(L))

现象表的操作ListDelete(&L,i,&e)在链表中的实现:

基本操作为:找到线性表中第i-1个结点,修改其指向后继的指针有序对<ai-1,ai><ai,ai+1>改变为<ai-1,ai+1>

04_007

Status ListDelete_L(LinkList L, int pos,  ElemType &e)

{

         p  = L;

         j  = 0;

         while(p->next  && j < pos)

         {

                   p  = p->next;

                   ++  j; //寻找第pos个结点,并令p指向其前驱

         }

         if(!(p->next)  || j > pos-1)

                   return  ERROR; //删除位置不合理

         q  = p->next;

         p->next  = q->next; //删除并释放结点

         e  = q->data;

         free(q);

         return  OK;

} //ListDelete_L

算法的时间复杂度为:O(ListLength(L))

 

05_001

void CreateList_L(LinkList &L, int n)

{

         L  = (LinkList) malloc(sizeof(LNode));

         L->next  = NULL; //先建立一个带头结点的单链表

         for(i  = n; i > 0; -- i)

         {

                   p  = (LinkList) malloc(sizeof(LNode));

                   scanf(&p->data);  // 输入元素值

                   p->next  = L->next;

                   L->next  = p; //插入到表头

         }

} // CreateList_L

算法的时间复杂度为:O(ListLength(L))

05_002

void union(List &La, List Lb)

{

         La_len  = ListLength(La);

         Lb_len  = ListLength(Lb);

         for(i  = 1; i <= Lb_len; i ++)

         {

                   GetElem(Lb,i,e);

                   if(!LocateElem(La,  e, equal())

                            ListInsert(La,  ++La_len, e)

         }

} //union

上述算法的时间复杂度:

控制结构:for循环

基本操作:LocateElem(La,e,equal())

当以顺序映像实现抽象数据类型线性表时为:)

当以链表映像实现抽象数据类型线性表时为:

05_003

void purge(List & La, List Lb)

{

         InitList(LA);

         La_len  = ListLength(La);

         Lb_len  = ListLength(Lb);

         for(i  = 1; i <= Lb_len; i ++)

         {

                   GetElem(Lb,  i, e);

                   if(!  equal(en, e))

                   {

                            ListInsert(La,  ++La_len, e);

                            en  = e;

                   }

         }

}

上述算法的时间复杂度:

控制结构:for循环

基本操作:GetElem(Lb, i, e)

当以顺序映像实现抽象数据类型线性表时为:

当以链表映像实现抽象数据类型线性表时为:

05_004

void MergeList(List La, List Lb, List  & Lc)

{

         InitList(Lc);

         i  = j = 1;

         k  = 0;

         La_len  = ListLength(La);

         Lb_len  = ListLength(Lb);

         while((i  <= La_len) && (j <= Lb_len))

         {

                   GetElem(La,  i, ai);

                   GetElem(Lb,  j, bj);

                   if(ai  <= bj)

                   {

                            ListInsert(Lc,  ++ k, ai);

                            ++  i;

                   }

                   else

                   {

                            ListInsert(Lc,  ++ k, bj);

                            ++  j;

                   }

         }

}

上述算法的时间复杂度:

控制结构:三个并列的while循环

基本操作:ListInsert(Lc, ++ k, bj);

当以顺序映像实现抽象数据类型线性表时为:

当以链表映像实现抽象数据类型线性表时为:

用上述定义的单链表实现线性表的操作时,存在的问题:

1.      单链表的表长是一个隐含的值;

2.      在单链表中的最后一个元素后插入元素时,需遍历整个链表;

3.      在链表中,元素的“位序”概念淡化,结点的“位置”概念强化。

改进链表的设置:

1.      增加“表长”,“表尾指针”和“当前位置的指针”三个数据域;

2.      将基本操作由位序“改为指针”

 

四、一个带头结点的线性表类型

05_005

typedef struct LNode

{

         //结点类型

         ElemType  data;

         struct  LNode *next;

} *Link, *Position;

Status MakeNode(Link &p, ElemType e);//分配由p指向的值为e的结点,并返回OK;

//若分配失败,则返回ERROR

void FreeNode(Line &p); //释放p所指结点

05_006

typedef struct

{//链表类型

         Link  head, tail; //指向头结点和最后一个结点

         int  len; //指示链表长度

         Link  current; //指向当前访问的结点的指针,

         //初始位置指向头结点

} LinkList;

链表的基本操作:

{结构初始化和销毁结构}

Status InitList(LinkList &L); //构造一个空线性链表L

//头指针、尾指针和当前指针均指向头结点,表长为零

Status DestoryList(LinkList &L); //销毁线性表LL不再存在

{引用类型}

Status ListEmpty(LinkList L); //叛表空

Int ListLength(LinkList L); //求表长

Status Prior(LinkList L);//改变当前指针指向其前驱

Status Next(LinkList L);//改变当前指针指向后继

ElemType GetCurElem(LinkList L); //返回当前指针所指数据元素

Status LocatePos(LinkList L, int i); //改变当前指针指向第i个结点

Status LocateElem(LinkList L, ElemTypee,Status(* compare)(ElemType, ElemType));

//若存在与e满足函数compare()判定关系的元素,则移动当前指针

//指向第1个满足条件的元素,并返回OK;否则返回ERROR

Status ListTraverse(LinkList L,Status(*visit)()); //依次对L的每个元素调用函数visit()

{加工型操作}

Status ClearList(LinkList & L);//重置为空表

Status SetCurElem(LinkList & L,ElemType e); //更新当前指针所指数据元素

Status Append(LinkList & L, Link s); //一串结点链接在最后一个结点之后

Status InsAfter(LinkList & L, ElemTypee); //将元素e插入在当前指针之后

Status DelAfter(LinkList & L, ElemType*e); //删除当前指针之后的结点

 

 

05_007

Status InsAfter(LinkList & L,  ElemType e)

{

         //若当前指针在链表中,则将数据元素e插入在线性表L

         //当前指针所指结点之后,则返回OK;否则返回ERROR

         if(!  L.current)

                   return  ERROR;

         if(!  MakeNode(s, e))

                   return  ERROR;

         s->next  = L.current->next;

         L.current->next  = s;

         return  0K;

} // InsAfter

 

 

05_008

Status DelAfter(LinkList & L,  ElemType & e)

{

         //若当前指针及其后继在链表中,则删除线性表L中当前指针

         //所指结点之后的结点,并返回OK,否则返回ERROR

         if(  !(L.current && L.current->next))

                   return  ERROR;

         q  = L.current->next;

         L.current->next  = q->next;

         e  = q->data;

         FreeNode(q);

         return  OK;

} // DelAfter

 

{利用上述定义的线性表可以完成线性表的其它操作}

 

例一:

 

05_009

Status ListInsert_L(LinkList L, int i,  ElemType e)

{

         //带头结点的单链线性表L的第i个元素之前插入元素e

         if(!  LocatePos(L, i-1))

                   return  ERROR; //插入在第i-1个结点之后

         else

                   return  ERROR;

} // ListInsert_L

 

 

05_010

void MergeList_L(LinkList & La,  LinkList & Lb, LinkList & Lc,

                                      int(*compare)(ElemType, ElemType)))

{

         if(!  InitList(Lc))

                   return  ERROR; //存储空间分配失败

         LocatePos(La,  0);

         LocatePos(Lb,  0); //当前指针指向头结点

         if(DelAfter(La,  e))

                   a  = e;

         else

                   a  = MAXC; //MAXC为常量最大值

         while(!  (a = MAXC && b = MAXC))

         {

                   //LaLb非空

                   ...

         }

         DestoryList(La);

         DestoryList(Lb);  //销毁链表LaLb

         return  OK;

} // MergeList_L

 

if((*compare)(a, b) <= 0)

{

         //  a <= b

         InsAfter(Lc,  a);

         if(DelAfter(La,  el)

                   a  = el;

         else

                   a  = MAXC;

}

else

{

         //  a > b

         InsAfter(Lc,s);

         if(DelAfter(Lb,  e)

                   b  = el;

         else

                   b  = MAXC

}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值