05

严蔚敏视频 笔记05

链表的生成操作

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; // 插入到表头

    }

}

 

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

 

基本操作 计数器和指针的关系

 

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);

}

时间复杂度:

控制结构:for循环

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

顺序映象时 时间复杂度为O(n^2)

链式映象时 时间复杂度为O(n^2)

 

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)

顺序映象时 时间复杂度为O(n)

链式映象时 时间复杂度为O(n^2)

 

尽量对其进行排序

 

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循环

基本操作:LisstInsert(Lc,++k,e)

顺序映象时 时间复杂度为O(两表长之和)

链式映象时 时间复杂度为O(两表长和的平方)

 

单链表实现线性表的操作存在的问题:

1.表长是一个隐含的值

2.在最后一个元素最后插入元素时需遍历整个链表

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

 

改进链表的位置:

1.增加“表长”、“表尾指针”、“当前位置的指针”

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

 

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

typedef struct LNode { // 结点类型

    ElemType data;

    struct LNode *next;

} *Link,*Position;

 

Status MakeNode(Link &p,ElemType e);

// 分配由p指向的值为e的结点,并返回OK;若分配失败则返回ERROR

 

void FreeNode(Link &p);

// 释放p所指结点

 

typedef struct { // 链表类型

    Link head,tail; // 分别指向线性链表中的头结点和最后一个结点

    int len; // 指示线性链表中数据元素的个数

} LinkList;

 

链表的基本操作:

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

 

Status InitList(LinkList &L);

// 构造一个空的线性链表L

 

Status DestroyList(LinkList &L);

// 销毁线性链表LL不再存在

 

{引用型操作}

Status ListEmpty(LinkList L);

// 判表空

int ListLength(Link L);

// 求表长

Status Prior(LinkList L);

// 改变当前指针指向其前驱

Status Next(LinkList L);

// 改变当前指针指向其后继

ElemType GetCrElem(LinkList L);

// 返回当前指针所指数据元素

Status LocatePos(LinkList L,int i);

// 改变当前指针指向第i个结点

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

// 若存在与e满足函数compare()判定关系的元素,则移动当前指针指向期一个满足条件的元素,并返回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,ElemType e);

// 将元素e插在当前指针之后

Status DelAfter(LinkList &L,ElemType *e);

// 删除当前指针之后的结点

 

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

比如ListInsert_LMergeList_L

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值