线性表的链式表示——数据结构

来源:互联网 发布:社交源码 编辑:程序博客网 时间:2024/06/05 17:00

  由于顺序结构存在的增删困难,还有其他操作也较为不方便的原因为了让结构更加灵活,多变,更充分利用存储空间,有了链表。

  在链式结构中,不同于顺序结构的通过存储位置上的关系来表示逻辑上的关系,链式结构中通过“箭头”——指针,的引导来表示相互关系。

  因此在链表中,将每个数据分为两部分:本生的数据部分(数据域),和相互关系的部分——指针域。

C语言的结构体如下:

                                

typedef struct LNode{            ElemType  data;            struct   LNode   *next;}

该结构的大概存储结构通过一个查找数据来分析:

Status GetElem_L(LinkList L,int i;ElemType &e){       p=L->next;       j=1;       while(p&&j<i)       {               p=p->next;               j++;         }         e=p->data;}              

该例子中,通过指针的“引导”实现了数据间的联系。


区别与顺序表中的增和删,由于链表关系有指针域来联系,因此在改变关系时候,只需要改变指针的“指引”就ok。

如增添数据:

主要的步骤就是该表增添位置的前一个结点的“指向”,以及添加结点的指向。类似于只需改变铁链中的2的“缺口”,而其他的结点并不需要改变。

s->next=p->next;p->next=s;
最终实现就是在添加一个遍历让指针指向需要增添的位置上and创建新结点。

Status ListInsert(LinkList& L,int i;ElemType e){for(p=L,j=0;p&&j<i-1;j++){         p=p->next;}s=(ElemType*)malloc(ElemType);s->data=e;s->next=p->next;p->next=s;return ok;}

删除一样,只不过要通过free()来释放删除掉的结点:

Status Linkdelete(LinkList &L,int i;ElemType &e){for(p=L,j=0;p&&j<i;j++){        p=->next;}q=p->next;p->next=p->next->next;e=q->data;free(q);return ok;}

综合运用是:2个链表的合并

算法思想与前一节一致,就是在最后剩余的部分链表上更加简便了。

void mergeList(Linklist& L1,LinkList& L2,LinkList& L3){         pa=L1->next;         pb=L2->next;         pc=L3=L1;         while(p1&&p2)         {                 if(p1->data<=p2->data)                   {                       p3->next=p1;                       p3=p1;                       p1=p1->next;                   }                  else{                  p3->next=p2;                  p3=p2;                  p2=p2->next;                  }            if(pa)              p3->next=p1;            if(pb)   p3->next=p2;}                       


以上是动态链表的建立,但是链表的本质就是多了一个指针域来代表逻辑关系,而不是用存储位置上的关系来表示,但是我们可以看出通过同样的数组类型同样可以添加一个“指针”来表示相互之间的关系,这就是——静态链表

就是创建一个新类:

typedef struct{           ElemType  data;//数据            int    cur;//等同于指针}

其中的 cur 代表数组中的“点”的下一个“点”的位置。

在增删数据的时候只需要同链表相同,改变“结点”的“指针”即可。

在数据的查询中虽然看似像链表,但实际上的查看顺序是按照数组的存储顺序依依查看的:

int LocateElem(SlinkList S,ElemType e){i=S[0].cur;//i表示查找到的位置while(i&&S[i].data!=e){i=S[i].cur;}return i;}

与链表的区别是,在增删中的开辟和释放没有了系统提供的函数,需要自己建立。

建立方法是建立一个“垃圾库”,删除的数就把它放进这个垃圾库中,需要的数就把它提出来。本质就是建立一个备用链表。

具体步骤为3步:1、将空间的数据初始化为一个静态链表。2、建立一个备用空间中得到一个节点。3、将节点连接到备用链表中。

第一步--初始化静态链表:

void InitSpace(SLinklist &space){for(i=0;i<MaxSize-1;i++)              space[i].cur=i+1;/*因为数组的下标是从0到n-1,而在静态链表中cur指向下一个节点*/space[MaxSize-1].cur=0;//最后的指针域为NULL}

第二步--从备用空间中得到一个结点。

第三步--链接

直接以(A-B)并(B-A)为例。

void difference(SLinkList & space,int i){InitSpace(space);S=mallocS(space);//生成头结点r=S;scanf(m,n)//A and B的元素个数for(int j=1;j<m;j++)//建立A的链表{        i=mallocS(space);        scanf(sapce[i].data);        space[r].cur=i;//插入到表尾        r=i;}space[r].cur=0;for(........).......//插入B/*指向A中元素分别查找,如果没有则放置到一个备份链表中。*/if(k==space[r].cur){        i=mallocS(space);        space[i].data=b;        space[i].cur=space[r].cur;        space[r].cur=i;}else /*说明元素已存在,删除掉*/}




















阅读全文
0 0
原创粉丝点击