zoukankan      html  css  js  c++  java
  • 第一章 线性表(2)——链式存储

    1、存储方式:

    用任意存储空间单元来存放线性表的各个元素,为了能体现元素之间的逻辑关系(线性),在存放每个元素的同时,也存放相关元素的信息(相关元素的存储地址),即用指针来表示元素之间的逻辑关系。存储一个元素占用的空间称为一个结点。

    2、特点:

    1)存储空间不一定连续;

    2)逻辑关系是由指针来体现的;

    3)逻辑上相邻,物理上不一定相邻;

    4)非随机存取(顺序存取),即访问任何一个元素的时间不同;

    3、分类:

    单链式存储结构:存放元素的同时,存放其后继(或前驱)元素的信息;

    双链式存储结构:存放元素的同时,存放其前驱后后继元素的信息;

    循环单链式存储结构:在单链式存储结构中,由于最后一个元素没有后继,其结点 的指针域为空,若在此记下第一个元素的存储地址,则形成循环单链式存储结构;

    循环双链式存储结构:在双链式存储结构中,最后一个元素结点的后继指针指向第一个元素结点,第一个元素的前驱指针指向最后一个元素结点。

    4、术语

    头指针:第一个元素的存储地址;

    头结点:有时为了方便,增加一个结点,其数据域不存放任何元素,其指针域存放第一个元素的存储地址;

    头结点指针:指向头结点的指针;

    5、虚拟实现:

    利用高级语言中的动态存储结构(即指针)来实现。

    //---线性表的单链式存储结构---
    typedef struct LNode
    {
        ElemType data;
        struct Lnode *next;    
    }LNode, *LinkList;

    6、实现:

    1)初始化

    //不带头结点
    int Initlist(LinkList L)
    {
        L=NULL;
        return OK;
    }
     
    //带头结点
    int Initlist(LinkList L)
    {
        L=(LNode*) malloc (sizeof(Lnode));
        L->next=NULL;
        reutrn OK;
    }
     

    2)求长度

    int length_L(LinkList L)
    {
        i=0;//计数
        p=L->next;
        while(P)
        {
        i++
        p=p->next;
        }
        return i;
    }

    3)访问第i个元素

    由于仅仅知道第一个元素的存储地址,第i个元素的地址不象顺序存储那样可以立即计算出来,所以必须利用元素的后继指针去找到指定元素的存储地址,然后访问它!

    即从头开始遍历每个元素,并且记数,看是否是指定元素。

    Status GetElem_L(LinkList L, int i, ElemType &e)
    {
        P=L->next; j=1;
        while(p&&j<1)
        {
        p=p->next;
        ++j;
        }
        if(!p||j>i) return ERROR;
        e=p->data;
        return OK;
    }

    4)插入某一个元素

    Status Listinsert_L(LinkList &L, int i, ELemType e)
    {
        //在带头结点的单链表L中第i个位置之前插入元素e
        p=L;j=0;
        while(p&&j<i-1){p=p->next; ++j;}
        if(!p||j>i-1)return ERROR;
        s=(LinkList)malloc(sizeof(LNode));
        s->data=e;s->next=p->next;
        p->next=s;
        reuturn OK;
    }

    5)删除p指元素的后继元素 p->next=p->next->next

    删除第i个元素:

    Statuc ListDelete_L(LinkList &L, int i, ElemType &e)
    //在带头结点的单链线性表L中,删除第i个元素,并由e返回其值
    {
        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;//或p->next=p->next->next
        e=q-data;free(q);
        return OK;
    }

    6)建立      输入线性表元素,以单链式存储方式存储,即创建单链表。

    方法1:从头到尾,即从第一个元素结点逐个创建各个元素结点。每次都是链到当前链表的最后。

    //创建头结点
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL; r=L;
    //读入一个元素,链入其中
    p=(LinkList)malloc(sizeof(LNode));
    scanf(&p->data);
    p->next=NULL;
    r->next=p; r=r->next;

    方法2:从尾到头,即从最后一个元素结点逐个创建各个元素结点。每次都是链到当前链表的前面,即头结点之后。

    //创建头结点
    L=(LinkList)malloc(sizeof(LNode));
    L->next=NULL;
    //读入一个元素,链入其中
    p=(LinkList)malloc(sizeof(LNode));
    scanf(&p->data);
    p->next=L->next;//使p->next为空
    L->next=p;

    7)归并  方法:可以在两个表上直接做,不需要开辟新空间,改变指针即可。

    //归并
    void MergeList_L(LinkList &La,LinkList &Lb, LinkList &Lc)
    {
        pa=La->next;pb=Lb->next;
        Lc=pc=La;
        while(pa&pb)
        {
            if(pa->data<=pb->data)
            {
            pc->next=pa;pc=pa;pa=pa->next;
            }
            else{pc->next=pb;pc=pb;pb=->next;}
        }
        pc->next=pa?pa:pb;
        free(Lb);
    }

    8、小结

    线性表的链式存储结构的方式,特点,分类

    线性表的单链式存储结构的虚拟实现

    线生表在单链式存储结构下操作的实现

    (如:初始化,求表长,取表中第i个元素,插入,删除,建立链表,归并等)

    9、拓展    双链表

    特点:具有单链表的特点 前驱操作简单  任何位置插入、删除都简单了(已知该位置指针)

    虚拟实现:

    typedef struct DuLNode
    {
        ElemType data;
        struct DulNode *next;
        struct DulNode *prior;
    }DulNode, *DuLinkList;

    循环双链式存储结构…。

  • 相关阅读:
    B-树和B+树的应用:数据搜索和数据库索引【转】
    与网络编程相关的信号:
    Reactor构架模式
    EINTR错误
    通讯链路的检测方法
    背景减法——自组织算法
    数据结构7_链二叉树
    背景减法——Vibe
    操作系统2_进程控制
    操作系统1_进程控制块PCB
  • 原文地址:https://www.cnblogs.com/shamoof/p/3662199.html
Copyright © 2011-2022 走看看