第9课- 静态链表

单链表完美解决了顺序表的问题!

还有其它改进顺序表的方法吗?

学生A:单链表很完美,我觉得顺序表可以退休了。

学生B:我也觉得 ,老师为什么还要教我们顺序表呢 ?

学生A:那不是为了展现单链表的强大嘛!

学生B:看来我们可以彻底抛弃顺序表了。

牛人小C出场。

顺序表有优势,单链表也同样有缺点!

学生C:单链表虽然综合起来胜过了顺序表,但是也有不足之处。

学生B:什么不足之处呢,Linux内核都用的单链表哦!

学生A:就是,一般的大型项目都能找到单链表的身影!

学生C:我想你们会明白的单链表的相对劣势,单链表的实现严重依赖指针!数据元素中必须包含一个额外的指针域!没有指针的程序设计语言无法实现!

一. 顺序表的改进

1. 静态链表的定义

(1)      顺序表数组中的元素由两个数据域组成:data和next。

(2)      data域用于存储数据。

(3)      next域用于存储下一个元素在数组中的下标。

2. 静态链表是在顺序表的基础上利用数组实现的单链表!

typedef struct _tag_StaticListNode

{

unsigned int data;

int next;

}TStaticListNode;

结点结构体定义

typedef struct _tag_StaticList

{

int capacity;

TStaticListNode header;

TStaticListNode node[];

}TStaticList;

静态链表结构体定义

二. 静态链表操作

1. 获取第pos个元素操作

(1)      判断线性变是否合法。

(2)      判断位置是否合法。

(3)      由表头开始通过next域一定pos次后,当前元素的next域即要获取的元素在数组中的下标。

sList->node[0] = sList->header;

for(i=0; i<pos; i++)

{

current = sList->node[current].next;

}

object = sLit->node[current].next;

2. 插入元素到位置pos的算法

(1)      判断线性表是否合法。

(2)      判断插入位置是否合法。

(3)      在数组中查找空闲位置index。

(4)      由表头开始通过next域移动pos次后,当前元素的 ,当前元素的next域为要插入的位置。

(5)      将新元素插入。

(6)      线性表长度加1。

for(i=0; (i<pos) && (sList->node[current].next != 0); i++)

{

current = sList->node[current].next;

}

sLisst->node[index].next = sLisst->node[current].next;

sLisst->node[current].next = index;

3. 删除第pos个元素的算法

(1)      判断线性表是否合法。

(2)      判断插入位置是否合法。

(3)      获取第pos个元素。

(4)      将第pos个元素从链表中删除。

(5)      线性表长度减1。

object = sLisst->node[current].next;

sLisst->node[current].next = sLisst->node[object].next;

三. 创建可复用静态链表

StaticList.h

#ifndef _STATICLIST_H_

#define _STATICLIST_H_

typedef void StaticList;

typedef void StaticListNode;

StaticList* StaticList_Create(int capacity);

void StaticList_Destroy(StaticList* list);

void StaticList_Clear(StaticList* list);

int StaticList_Length(StaticList* list);

int StaticList_Capacity(StaticList* list);

int StaticList_Insert(StaticList* list, StaticListNode* node, int pos);

StaticListNode* StaticList_Get(StaticList* list, int pos);

StaticListNode* StaticList_Delete(StaticList* list, int pos);

#endif

StaticList.c

#include <stdio.h>

#include <malloc.h>

#include "StaticList.h"

#define AVAILABLE -1

typedef struct _tag_StaticListNode

{

unsigned int data;

int next;

} TStaticListNode;

typedef struct _tag_StaticList

{

int capacity;

TStaticListNode header;

TStaticListNode node[];

} TStaticList;

StaticList* StaticList_Create(int capacity) // O(n)

{

TStaticList* ret = NULL;

int i = 0;

if( capacity >= 0 )

{

ret = (TStaticList*)malloc(sizeof(TStaticList) + sizeof(TStaticListNode) * (capacity + 1));

}

if( ret != NULL )

{

ret->capacity = capacity;

ret->header.data = 0;

ret->header.next = 0;

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

{

ret->node[i].next = AVAILABLE;

}

}

return ret;

}

void StaticList_Destroy(StaticList* list) // O(1)

{

free(list);

}

void StaticList_Clear(StaticList* list) // O(n)

{

TStaticList* sList = (TStaticList*)list;

int i = 0;

if( sList != NULL )

{

sList->header.data = 0;

sList->header.next = 0;

for(i=1; i<=sList->capacity; i++)

{

sList->node[i].next = AVAILABLE;

}

}

}

int StaticList_Length(StaticList* list) // O(1)

{

TStaticList* sList = (TStaticList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->header.data;

}

return ret;

}

int StaticList_Capacity(StaticList* list) // O(1)

{

TStaticList* sList = (TStaticList*)list;

int ret = -1;

if( sList != NULL )

{

ret = sList->capacity;

}

return ret;

}

int StaticList_Insert(StaticList* list, StaticListNode* node, int pos)  // O(n)

{

TStaticList* sList = (TStaticList*)list;

int ret = (sList != NULL);

int current = 0;

int index = 0;

int i = 0;

ret = ret && (sList->header.data + 1 <= sList->capacity);

ret = ret && (pos >=0) && (node != NULL);

if( ret )

{

for(i=1; i<=sList->capacity; i++)

{

if( sList->node[i].next == AVAILABLE )

{

index = i;

break;

}

}

sList->node[index].data = (unsigned int)node;

sList->node[0] = sList->header;

for(i=0; (i<pos) && (sList->node[current].next != 0); i++)

{

current = sList->node[current].next;

}

sList->node[index].next = sList->node[current].next;

sList->node[current].next = index;

sList->node[0].data++;

sList->header = sList->node[0];

}

return ret;

}

StaticListNode* StaticList_Get(StaticList* list, int pos)  // O(n)

{

TStaticList* sList = (TStaticList*)list;

StaticListNode* ret = NULL;

int current = 0;

int object = 0;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->header.data) )

{

sList->node[0] = sList->header;

for(i=0; i<pos; i++)

{

current = sList->node[current].next;

}

object = sList->node[current].next;

ret = (StaticListNode*)(sList->node[object].data);

}

return ret;

}

StaticListNode* StaticList_Delete(StaticList* list, int pos) // O(n)

{

TStaticList* sList = (TStaticList*)list;

StaticListNode* ret = NULL;

int current = 0;

int object = 0;

int i = 0;

if( (sList != NULL) && (0 <= pos) && (pos < sList->header.data) )

{

sList->node[0] = sList->header;

for(i=0; i<pos; i++)

{

current = sList->node[current].next;

}

object = sList->node[current].next;

sList->node[current].next = sList->node[object].next;

sList->node[0].data--;

sList->header = sList->node[0];

sList->node[object].next = AVAILABLE;

ret = (StaticListNode*)(sList->node[object].data);

}

return ret;

}

main.c

#include <stdio.h>

#include <stdlib.h>

#include "StaticList.h"

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main(int argc, char *argv[])

{

StaticList* list = StaticList_Create(10);

int index = 0;

int i = 0;

int j = 1;

int k = 2;

int x = 3;

int y = 4;

int z = 5;

StaticList_Insert(list, &i, 0);

StaticList_Insert(list, &j, 0);

StaticList_Insert(list, &k, 0);

for(index=0; index<StaticList_Length(list); index++)

{

int* p = (int*)StaticList_Get(list, index);

printf("%d\n", *p);

}

printf("\n");

while( StaticList_Length(list) > 0 )

{

int* p = (int*)StaticList_Delete(list, 0);

printf("%d\n", *p);

}

printf("\n");

StaticList_Insert(list, &x, 0);

StaticList_Insert(list, &y, 0);

StaticList_Insert(list, &z, 0);

printf("Capacity: %d Length: %d\n", StaticList_Capacity(list), StaticList_Length(list));

for(index=0; index<StaticList_Length(list); index++)

{

int* p = (int*)StaticList_Get(list, index);

printf("%d\n", *p);

}

StaticList_Destroy(list);

return 0;

}

小结

l  静态链表其实是单链表的另一种实现方式。

l  静态链表的实现“媒介”不是指针而是数组。

l  静态链表主要用于不支持指针的程序设计语言中。

l  静态链表的实现是一种内存管理的简易方法。

思考:为什么静态链表结构体中要再定义个header成员,而不直接使用node[0]?

转载于:https://www.cnblogs.com/free-1122/p/11322736.html

数据-第9课-静态链表相关推荐

  1. 高级线性表——静态链表(最全静态链表解读)

    写在前面:博主是一位普普通通的19届双非软工在读生,平时最大的爱好就是听听歌,逛逛B站.博主很喜欢的一句话花开堪折直须折,莫待无花空折枝:博主的理解是头一次为人,就应该做自己想做的事,做自己不后悔的事 ...

  2. 数据结构-静态链表创建

    静态链表: 也是一种线性存储结构,它结合了顺序表和链表的优点,既能快速访问元素,又能快速增加或删除数据元素.使用静态链表存储数据,数据全部存储在数组中(和顺序表一样),但存储位置是随机的,数据之间&q ...

  3. 《大话数据结构》5一文学会数据结构中的静态链表存储结构(概念,实例,代码)

    静态链表 1.静态链表基本介绍 (1)静态链表:用数组来代替指针,来描述单链表.我们把用数组描述下标的链表叫做静态链表.也叫游标实现法. (2)首先让数组的元素是两个数据域组成,data 和cur.也 ...

  4. 可由一个尾指针唯一确定的链表有_L2数据结构第08课 单向链表和循环链表

    L2-数据结构-第08课 单向链表和循环链表 线性表 线性表是一种常用的数据结构,其中的每一个元素(结点)都有唯一的前驱和唯一的后续.当然,第一个元素只有后续,最后一个元素只有前驱. 线性表一般分为& ...

  5. 数据结构与算法(2-2)线性表之链式存储(单链表、静态链表、循环链表、双向循环链表)

    目录 一.单链表 1.存储方式 2.插入 3.删除 总代码: 二.静态链表 1.存储方式 2.插入 3.删除 4.遍历 总代码: 三.循环链表 总代码: 四.双向循环链表 1.存储方式: 2.插入和删 ...

  6. 静态链表实现(A-B)+(B-A)【代码】

    -----------------------------------------------第一次发代码,写在前面------------------------------------------ ...

  7. java静态链表_数据结构笔记:静态链表(C语言)

    void CreateList(StaticLinkList *P)//创建一个静态链表 { int i; for(i=0;i此时并没有已占用空间,所以第一个节点中的指针(cur)的值为1,也就是说空 ...

  8. 静态链表的插入和删除

    静态链表相当于是用一个数组来实现线性表的链式存储结构,在静态链表中操作的是数组. 结构体数组 一.静态链表的插入操作 静态链表的插入操作包含两部分,首先是获得空闲量的下标,程序代码如下; int ge ...

  9. java静态链表_用Java实现一个静态链表

    什么是静态链表? 对于线性链表,也可用一维数组来进行描述.这种描述方法便于在没有指针类型的高级程序设计语言中使用链表结构. 用数组描述的链表,即称为静态链表. 在C语言中,静态链表的表现形式即为结构体 ...

  10. 从C语言的角度重构数据结构系列(四)-静态链表动态链表

    前言 是否存在一种存储结构,可以融合顺序表和链表各自的优点,从而既能快速访问元素,又能快速增加或删除数据元素. 在这里给自己打个广告,需要的小伙伴请自行订阅. python快速学习实战应用系列课程 h ...

最新文章

  1. java serializable用法_JAVA序列化Serializable及Externalizable区别详解
  2. 【JavaScript 1—基础知识点】:宏观概述
  3. CentOS上 Mono 3.2.8运行ASP.NET MVC4经验
  4. uva 11997 K Smallest Sums 优先队列处理多路归并问题
  5. 2c语言程序设计_大学生学C语言的理由是什么
  6. vue 地图使用navigator_初识ABP vNext(6):vue+ABP实现国际化
  7. c 定义结构体时提示应输入声明_C|语法的合理性理解和分析
  8. C语言项目大作业万历年,用C语言编写万历,详细代码.doc
  9. 获取代理电脑的https证书方法
  10. visio软件接口流程图_使用VISIO软件绘制系统框图及流程图的方法
  11. SQL列转行/行转列
  12. JUC笔记-同步器(AQS原理、ReentrantLock原理)
  13. 离职原因该怎么回答?
  14. 小马激活工具拒绝访问cannot open file c:\oemsf解决方法
  15. TypeScript学习--Symbols
  16. OpenCV 透射变换
  17. 用自己的路由器建立自己的服务器之创建网页
  18. wifi营销小程序源码+搭建教程
  19. Android图表年度最强总结,一篇文章从入门到精通!
  20. 人工智能传奇——关于AI起源与发展的故事

热门文章

  1. Flink Forward Asia 2020,明天见!
  2. freebsd mysql tmp_FreeBSD下安装MySQL与MySQLdb笔记
  3. python中矩阵除法_Python numpy矩阵处理运算工具用法汇总
  4. redistemplate 设置永不过期_解决密码已过期,拒绝访问问题
  5. os.system 获取打印值_react获取触发元素的属性 e.target.dataset
  6. java valid payload_Spring Validation最佳实践及其实现原理,参数校验没那么简单!
  7. linux环境下,Tomcat详细部署步骤
  8. dlib 怎么安装vs2017_VS2017+DLib_19.17详细配置教程
  9. 计算机专业中专自我鉴定范文,计算机专业中专生自我鉴定范文
  10. linux ls 输出格式,(转)linux 中使用ls指定输出时间格式