1,我们研究数据结构的操作,第一要弄懂它的结构体表示(也就是结构体特点)、第二要清楚它的初始化和撤销过程。对于静态链表首先分析它的特点:一是采用静态存储方式,二是没有指针。静态链表就是不用指针来表示链式关系的一种巧妙实现。

2,静态链表的结构体定义

1 #define MAX 100
2
3 typedef struct
4 {
5 int data; //数据域的类型可以是任意的基类型,包括数组
6 int cur;
7 }component, slinklist[MAX]

3,静态链表的初始化示意图

4,静态链表的操作集合,与单链表一致,均在头文件defs.h中。此头文件在前面文章中已经写出。

5,初始化操作的实现

 1 #include"defs.h"
2
3 void InitList(slinklist s)
4 {
5 int i;
6 L[MAX-1].cur = 0; //令链表头结点为空
7
8 for (i=0; i<MAX-2; i++) //其余元素构成备用链表
9 L[i].cur = i+1;
10 L[MAX-2].cur = 0; //备用链表最后一个元素置为空
11 }

InitList.c

6,静态链表撤销操作的实现,原理就是将链表从第一个元素至最后一个元素插入到备用链表第一个元素前

 1 #include"defs.h"
2
3 void DestroyList(slinklist s)
4 {
5 int i = L[MAX-1].cur;
6 L[MAX-1].cur = 0; //令头结点指向空
7
8 int k = L[0].cur;
9 L[0].cur = i; //令备用链表头结点指向链表第一个结点
10
11 int j; //用j来记录链表最后一个结点的位序
12 while (i)
13 {
14 j = i;
15 i = L[i].cur; //第i个结点的指针域为空,结束循环,j记录了最后一个结点
16 }
17 L[j].cur = k; //令链表最后一个结点指向备用链表第一个结点
18 }

DestroyList.c

7,静态链表清空操作和撤销操作是一致的。
8,判断空操作。ListEmpty.c

1 #include"defs.h"
2
3 int ListEmpty(slinklist s)
4 {
5 if (L[MAX-1].cur == 0)
6 return 0; //返回0代表为空
7 else
8 return 1; //非0代表不为空
9 }

ListEmpty.c

9,求链表长度操作.

 1 #include"defs.h"
2
3 int ListLength(slinklist s)
4 {
5 int i, j=0;
6 i = L[MAX-1].cur; //i指向第一个结点
7
8 while (i) //最后一个结点的指针域为空,结束循环
9 {
10 ++j;
11 i = L[i].cur;
12 }
13 return j;
14 }

ListLength.c

10,取元素操作.

 1 #include"defs.h"
2
3 int GetElem(slinklist s, int i, int *e)
4 {
5 int j=1, k = L[MAX-1].cur;
6 if (i<1 || i>ListLength(s)) //判断位置是否合理
7 exit(0);
8 while (k && j<i) //找到第i个位置
9 {
10 ++j;
11 k = L[k].cur;
12 }
13 *e = L[k].data;
14 return 0;
15 }

GetElem.c

11,查找元素操作实现.

 1 #include"defs.h"
2
3 int LocateElem(slinklist s, int e)
4 {
5 int i = L[MAX-1].cur;
6 int j = 0;
7 while (i)
8 {
9 ++j; //j作为计数器
10 if (L[i].data == e)
11 return j;
12 i = L[i].cur;
13 }
14 return 0;
15 }
16
17 //i仅是表示其元素的数组下标值,并不是位序

LocateElem.c

12,求前驱操作实现.

 1 #include"defs.h"
2
3 int PriorElem(slinklist L, int cur_e, int *pri_e)
4 {
5 int i = L[MAX-1].cur;
6 int j;
7 while (i)
8 {
9 j = L[i].cur;
10 if (j && L[j].data == cur_e)
11 {
12 *pri_e = L[i].data;
13 return 0;
14 }
15 i = j;
16 }
17 return 0;
18 }

PriorElem.c

13,求后继操作的实现

 1 #include"defs.h"
2
3 int NextElem(slinklist L, int cur_e, int *nex_e)
4 {
5 int i = L[MAX-1].cur;
6 int j;
7 while (i)
8 {
9 j = L[i].cur;
10 if (j && L[i].data == cur_e)
11 {
12 *nex_e = L[j].data;
13 return 0;
14 }
15 i = j;
16 }
17 return 0;
18 }

NextElem.c

14,Malloc函数实现

 1 //因为没有指针,没有动态分配函数,所以要自己实现
2
3 #include"defs.h"
4
5 int Malloc(slinklist L) //释放备用链表第一个结点
6 {
7 int i = L[0].cur;
8 if (i == 0) //备用链表为空,无法分配,退出
9 exit(0);
10 L[0].cur = L[i].cur; //备用链表头结点,指向备用链表第二个结点
11 return i;
12 }

15,Free函数实现

1 #include"defs.h"
2
3 void Free(slinklist L, int k) //将位置为k的空闲结点释放
4 { //即插入到备用链表第一个结点前
5 L[k].cur = L[0].cur;
6 L[0].cur = k;
7 }
8
9 //Malloc、Free均是对备用链表的操作

16,静态链表插入操作实现

 1 #include"defs.h"
2
3 int ListInsert(slinklist L, int i, int e)
4 {
5 int k = L[MAX-1].cur; //k指向第一个结点
6 int j = 1, m, s;
7
8 if (i<1 || i>ListLength(L)+1) //判断位置是否合理
9 exit(0);
10
11 while (k && j<i-1) //找到第i-1个位置
12 {
13 ++j;
14 k = L[k].cur;
15 }
16 m = L[k].cur; //m指向第i个位置
17
18 s = Malloc(L); //分配一个结点s
19 L[s].data = e;
20 L[s].cur = L[m].cur;
21 L[k].cur = s;
22 return 0;
23 }

ListInsert.c

17,静态链表删除操作的实现

 1 #include"defs.h"
2
3 int ListDelete(slinklist L, int i, int *e)
4 {
5 int k = L[MAX-1].cur;
6 int j = 1, m;
7 if (i<1 || i>ListLength(L)) //判断位置是否合理
8 exit(0);
9
10 while (k && j<i-1) //找到第i-1个位置
11 {
12 ++j;
13 k = L[k].cur;
14 }
15 m = L[k].cur; //m指向第i个位置
16 *e = L[m].data;
17 L[k].cur = L[m].cur;
18 Free(L, m); //将空闲结点m释放到备用链表中
19 }

ListDelete.c

18,遍历静态链表操作实现

 1 #include"defs.h"
2
3 void TravelList(slinklist L)
4 {
5 int j = 0;
6 int i = L[MAX-1].cur;
7
8 while (i)
9 {
10 ++j;
11 printf("第%d个结点为:%d\n", j, L[i].data);
12 i = L[i].cur;
13 }
14 }

TravelList.c

C语言实现--静态链表的操作的更多相关文章

  1. 使用C语言描述静态链表和动态链表

    静态链表和动态链表是线性表链式存储结构的两种不同的表示方式. 静态链表的初始长度一般是固定的,在做插入和删除操作时不需要移动元素,仅需修改指针,故仍具有链式存储结构的主要优点. 动态链表是相对于静态链 ...

  2. 数据结构(C语言版)链表相关操作算法的代码实现

    这次实现的是带头结点的单链表的初始化.遍历.创建.插入.删除.判断链表是否为空.求链表长度函数,编译环境是vs2013. 其中插入和删除函数中循环的条件目前还不太明白. #include<ios ...

  3. 静态链表-C语言实现

    1.静态链表是在没有指针的编程语言里对链表的一种实现2.主要是用数组模拟指针3.在这里,使用结构体使数组的每一个空间可以存储一个数据元素(date)和一个游标(cur),游标的作用相当于链表的指针域, ...

  4. 静态链表 C语言描述

    静态链表1.下标为0的游标存放最后存放数据节点的游标,即是第一个没有存放元素(备用链表)的下标2.最后一个的节点存放第一个由数值得下标3.第一个和最后一个都不存放数据 即是备用链表的第一个的下标 4. ...

  5. 深入浅出数据结构C语言版(5)——链表的操作

    上一次我们从什么是表一直讲到了链表该怎么实现的想法上:http://www.cnblogs.com/mm93/p/6574912.html 而这一次我们就要实现所说的承诺,即实现链表应有的操作(至于游 ...

  6. 数据结构6: 静态链表及C语言实现

    本节继续介绍线性表的另外一种链式表示——静态链表.(前面介绍的链表称为 动态链表 ). 逻辑结构上相邻的数据元素,存储在指定的一块内存空间中,数据元素只允许在这块内存空间中随机存放,这样的存储结构生成 ...

  7. C语言提高 (6) 第六天 文件(续) 链表的操作

    1昨日回顾 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include &l ...

  8. C语言之----面向对象的方法实现链表的操作

    1 /* 2 * 详细运行过程: 本程序实现的是对链表的简单的操作,即链表的增 删 改 查 销毁 初始化 3 * 运用面向对象的思想,实现一个类op,op中包括了所有的链表操作方法 4 * 其他的程序 ...

  9. 玩转C语言链表-链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个"头指针"变量,以head表示,它存放一个地址.该地址指向一个元素 ...

随机推荐

  1. CentOS7上安装jdk,mysql

    最近笔者的云服务器由于中毒,重装系统了... 所以就记录下所有服务的搭建过程吧 1.安装jdk 在oracle上下载linux系统的jdk,笔者这里使用的是1.8 https://www.oracle ...

  2. SpringBoot同时接收单个对象和List<object>参数

    最近做项目的有个需求,是把多个文件移动到另一个文件夹下,这需要把 新的文件夹id -- Long类型 多个文件的信息 -- List< Object > 类型 这两个参数传给后台,我的后台 ...

  3. Hash Tables and Hash Functions

    Reference: Compuer science Introduction: This computer science video describes the fundamental princ ...

  4. Openstack OCATA 安装环境说明(一) 未完成版本

    1 Openstack简介: 2 实验说明: 3 图例: 4 实验环境说明: 4.1 ) 网卡说明: 网卡名 网 段 连接方式 说明 eth0 10.10.5.0/24 仅主机网络 内部网络自动以IP ...

  5. Mybatis 报错java.sql.SQLException: No suitable driver found for http://www.example.com

    运行项目报错 Error querying database. Cause: java.sql.SQLException: No suitable driver found for http://ww ...

  6. mysqlbinlog :unknown variable 'default-character-set=gbk'

    mysqlbinlog :unknown variable 'default-character-set=gbk'  解决方法: 在命令行中加入--no-defaults开关,使用mysqlbinlo ...

  7. innodb日志文件大小

    innodb是用多个文件作为一组循环日志,通常不需要修改默认的日志数量,只修改每个日志文件的大小即可,要修改日志文件大小,需要完全关闭mysql,将旧的日志文件移到其他地方保存,重新配置参数,然后重启 ...

  8. 【MySQL】CentOS7中使用systemctl工具管理启动和停止MySQL

    centos7以前版本,可以使用这个/etc/init.d/mysqld start 来启动mysql 但是centos7之后,通过systemctl start mysqld.service 这个要 ...

  9. Linux三剑客grep、awk和sed

    grep,sed 和 awk是Linux/Unix 系统中常用的三个文本处理的命令行工具,称为文本处理三剑客.本文将简要介绍这三个命令并给出基本用法. 管道 在介绍这两个命令之前,有必要介绍一下Uni ...

  10. 使用memory_profiler异常

    在使用memory_profiler模块0.55.0版本执行命令诊断程序内存用量时,遇到下面错误: C:\Users\Chen\Desktop\python_doc\第四模块课件>python ...