数据结构---线性表----静态链表
2016-03-23 13:02
288 查看
1.静态链表的定义
对于一些高级语言,由于没有指针,链表结构按照前面的结构无法实现。故有人提出了用数组的元素来代替指针,来描述单链表。
首先我们让数组的元素都是由两个数据域组成。data和cur。也就是说,数组的每个下标都对应一个Data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数据;而cur相当于单链表中next指针,存放该元素的后继在数组中的小标,我们把cur叫做游标。
我们把这种用数组描述的链表叫做静态链表。我们把这种描述方法还有起名叫做游标实现法。
我们对数组的第一个和最后一个元素作为特殊元素处理,不存数据。我们通常把未被使用的数据元素称为备用链表。而数组第一个元素,即小标为0的元素的则存放在备用链表。而数组的最后一个元素的cur则存在第一个有数值的元素的下标,相当于单链表中的头结点作用,当整个链表为空时,则为0*0。
现在我们将数据存入静态链表。
2.静态链表的插入操作
静态链表中要解决的是:如何用静态模拟动态链表结构的存储空间的分配,需要时申请,无用时释放。
动态链表中,结点申请和释放分别借用malloc()和free()两个函数来实现。在静态链表中操作的是数组,不存在像动态链表的结点申请和释放问题,所以我们需要自己实现这两个函数,才可以进行插入和删除操作。
解决办法:将所有未被使用过的及已经删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上去得第一个结点作为待插入的新结点。
这段代码其实就是:返回一个下标值,就是数组头元素的cur存的第一个空闲的下标。同时把该分量的cur值给头元素之后就可以继续分配新的空闲分量。
插入操作的实现代码:
3.静态链表的删除操作
要执行删除操作时,原来要释放结点的函数free().现在我们也得自己实现这个操作;
3.得到静态链表的元素个数
4.静态链表优缺点
总结下他的优缺点:
优点: 在插入和删除操作时,只需要修改游标,不需要移动元素,从而改变了在顺序存储结构中的插入和删除操作需要移动大量的元素。
缺点: 1.没有解决连续存储分配带来的的表长难以确定的问题。
2.失去了顺序存储结构随机存取的特性。
对于一些高级语言,由于没有指针,链表结构按照前面的结构无法实现。故有人提出了用数组的元素来代替指针,来描述单链表。
首先我们让数组的元素都是由两个数据域组成。data和cur。也就是说,数组的每个下标都对应一个Data和一个cur。数据域data,用来存放数据元素,也就是通常我们要处理的数据;而cur相当于单链表中next指针,存放该元素的后继在数组中的小标,我们把cur叫做游标。
我们把这种用数组描述的链表叫做静态链表。我们把这种描述方法还有起名叫做游标实现法。
/*线性表的静态链表存储结构*/ #define MAXSIZE 1000 typedef struct { Elemtype data; int cur; /*游标(Cursor),为0时表示无指向*/ }component, StaticLinkList[MAXSIZE];
我们对数组的第一个和最后一个元素作为特殊元素处理,不存数据。我们通常把未被使用的数据元素称为备用链表。而数组第一个元素,即小标为0的元素的则存放在备用链表。而数组的最后一个元素的cur则存在第一个有数值的元素的下标,相当于单链表中的头结点作用,当整个链表为空时,则为0*0。
/*将一维数组space中各分量链成一备用链表,*/ /*space[0].cur为头指针,“0”表示空指针*/ Status InitList(StaticLinkList space) { int i; for (i = 0; i < MAXSIZE - 1;i++) space[i].cur = i+1; space[MAXSIZE-1].cur = 0; return OK; }
现在我们将数据存入静态链表。
2.静态链表的插入操作
静态链表中要解决的是:如何用静态模拟动态链表结构的存储空间的分配,需要时申请,无用时释放。
动态链表中,结点申请和释放分别借用malloc()和free()两个函数来实现。在静态链表中操作的是数组,不存在像动态链表的结点申请和释放问题,所以我们需要自己实现这两个函数,才可以进行插入和删除操作。
解决办法:将所有未被使用过的及已经删除的分量用游标链成一个备用的链表,每当进行插入时,便可以从备用链表上去得第一个结点作为待插入的新结点。
/*若备用链表非空,则返回分配的结点下标,否则返回0*/ int Malloc_SLL(StaticLinkList space) { int i = space[0].cur; /*当前数组第一个元素的cur存的值*/ /*就是要返回的第一个备用空闲的下标*/ if (space[0].cur) space[0].cur = space[i].cur;/*由于要拿出一个分量来使用了,所以我们就得把他的下一个分量当作备用*/ return i; }
这段代码其实就是:返回一个下标值,就是数组头元素的cur存的第一个空闲的下标。同时把该分量的cur值给头元素之后就可以继续分配新的空闲分量。
插入操作的实现代码:
/*在L中第i个元素之前插入新的数据元素e*/ int ListInsert(StaticLinkList L, int i, ElemType e) { int j ,k, l; k = MAXSIZE - 1 ; /*注意首先是最后一个元素的下标*/ if (i<1 || i> Listlength(L) + 1) return ERROR; j = Malloc_SLL(L); /*获得空闲下来的下标*/ if (j) { L[j].data = e; /*将数据赋值给次分量的data*/ for (l =1 ; l <= i -1; l++) /*找到第i个元素之前的位置*/ k = L[k].cur; L[j].cur = L[i].cur; /*把第i个元素之前的cur赋值给新元素的cur*/ L[k].cur = j; /*把新元素的下标赋值给第i个元素之前的元的cur*/ return OK; } return ERROR; }
3.静态链表的删除操作
要执行删除操作时,原来要释放结点的函数free().现在我们也得自己实现这个操作;
/*删除在L中第i个数据元素e*/ Status ListDelete(StaticLinkList L, int i) { int j , k; if (i < 1 || i > ListLength(L)) return ERROR; k = MAXSIZE - 1; for(j = 1, j <= i - 1; j ++ ) k = L[k].cur; j = L[k].cur; L[k].cur = L[j].cur; Free_SSL(L, j); return OK; }
/*将下标为k的空闲节点回收到备用链表*/ void Free_SSL(StaticLinkList space, int k) { space[k].cur = spce[0].cur; /*把第一个元素cur值给赋给要删除的分量cur*/ space[0].cur = k; /*把要删除的分量下标赋值给第一个元素的cur*/ }
3.得到静态链表的元素个数
/*初始条件,静态链表L已经存在,操作结果,返回L中的数据元素个数*/ int ListLength(StaticLinkList L) { int j = 0; int i = L[MAXSIZE - 1].cur; while(i) { i = L[i].cur; j++; } return j; }
4.静态链表优缺点
总结下他的优缺点:
优点: 在插入和删除操作时,只需要修改游标,不需要移动元素,从而改变了在顺序存储结构中的插入和删除操作需要移动大量的元素。
缺点: 1.没有解决连续存储分配带来的的表长难以确定的问题。
2.失去了顺序存储结构随机存取的特性。
相关文章推荐
- 数据结构---线性表----静态链表
- 数据结构---线性表----静态链表
- 数据结构---线性表----静态链表
- Python 数据结构与算法——二叉搜索树的实现
- 二叉树的先序、中序、后序遍历
- 数据结构实验1-3
- 数据结构实验1-2
- MySQL索引背后的数据结构及算法原理
- Python 数据结构与算法——快排
- 双链表按访问频度域freq的值的递减序排列
- 将双链表中值为x的节点置为首节点
- 单链表的基本运算
- 顺序表的基本运算
- Python 数据结构与算法——选取算法(TopK)
- 数据结构8-排序1
- 数据结构---线性表----单链表结构与顺序存储结构的对比
- 数据结构---线性表----单链表结构与顺序存储结构的对比
- 数据结构---线性表----单链表结构与顺序存储结构的对比
- 数据结构---线性表----单链表结构与顺序存储结构的对比
- 数据结构---线性表----单链表结构与顺序存储结构的对比