数据结构总目录

本章目录

  • (一)静态链表图文解析
  • (二)静态链表代码解析
    • 1. 基本操作
      • 1.1 存储结构
      • 1.2 初始化
      • 1.3 插入数据
      • 1.4 删除数据
      • 1.5 修改数据
    • 2. 源代码及测试
      • 2.1 源代码
      • 2.2 测试结果

(一)静态链表图文解析

静态链表结构

  • 静态链表的结构实际上就是一个数组,静态链表的数组中,每一个元素代表一个结点,结点同样和链表一样包括数据域和指针域
  • 只是在静态链表中的指针域不再是指针指向下一个结点的地址,而是用于存储下一个结点的数组下标,这样同样可以实现结点之间的连接关系

图示

在静态链表中

  • 指针域大于0,则代表下一个结点的数组下标
  • 指针域等于-1,则代表下一个结点为空
  • 指针域等于-2,则代表该结点尚未被使用

(二)静态链表代码解析

1. 基本操作

1.1 存储结构

#define MaxSize 10   //最大链表长度typedef char DataType;
typedef struct LNode
{DataType data; //数据域int next;      //指针域
}StaticList;

1.2 初始化

void InitList(StaticList **L)
{// 为静态链表分配空间(*L) = (StaticList *)malloc(MaxSize * sizeof(StaticList));// 初始化头结点StaticList *s = *L;s[0].data = '\0';s[0].next = -1;// 初始化链表int i;for (i = 1; i < MaxSize; i++){s[i].data = '\0';s[i].next = -2;}printf("已初始化链表\n");
}

1.3 插入数据

头部插入

void HeadInsert(StaticList *L)
{if (L){DataType x;printf("请输入插入的数据:");fflush(stdin);scanf("%c", &x);// 获取新结点的下标位置int free_node = GetFreeNodeIndex(L);if (free_node > 0){// 设置新结点的数据L[free_node].data = x;// 新结点指向链表的第一个结点L[free_node].next = L[0].next;// 头结点指向新结点,使得新结点成为链表的第一个结点L[0].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 链表空间已满!\n");}       }else{printf("插入失败! 链表已销毁!\n");}
}

尾部插入

void TailInsert(StaticList *L)
{if (L){int i;DataType x;printf("请输入插入的数据:");fflush(stdin);scanf("%c", &x);int free_node = GetFreeNodeIndex(L);if (free_node > 0){int tail_index = 0;// 查找尾结点下标while (L[tail_index].next > 0){tail_index = L[tail_index].next;}// 设置新结点数据L[free_node].data = x;// 新结点指针域设置为空L[free_node].next = -1;//尾结点指向新结点,使得新结点成为链表的最后一个结点L[tail_index].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 链表空间已满\n");}}else{printf("插入失败! 链表已销毁!\n");}
}

按位置插入

void LocateInsert(StaticList *L)
{if (L){int i, k;DataType x;printf("请输入插入的数据和插入位置:");scanf("%d %c", &k, &x);int free_node = GetFreeNodeIndex(L);if (k > 0 && free_node > 0){int insert_index = 0;// 查找链表中第(k-1)个结点while((--k) && L[insert_index].next > 0){   insert_index = L[insert_index].next;}// 插入新结点if (k == 0){// 设置新结点数据L[free_node].data = x;// 新结点指向第k个结点下标L[free_node].next = L[insert_index].next;// 第(k-1)个结点指向新结点L[insert_index].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 插入位置不合法!\n");}}else{printf("插入失败! 插入位置不合法/链表空间已满!\n");}}else{printf("插入失败! 链表已销毁!\n");}
}

1.4 删除数据

头部删除

void HeadDelete(StaticList *L)
{if (L){if (L[0].next > 0){int first_index;// 获取第一个结点first_index = L[0].next;// 头结点指向第二个结点L[0].next = L[first_index].next;// 初始化第一个结点L[first_index].data = '\0';L[first_index].next = -2;printf("删除成功!\n");}else{printf("删除失败! 链表为空!\n");}}else{printf("删除失败! 链表已销毁!\n");}
}

尾部删除

// 尾部删除
void TailDelete(StaticList *L)
{if (L){if (L[0].next > 0){int i = 0, j = 0;// 查询倒数第一个结点(i)和倒数第二个结点(j)while (L[i].next > 0){j = i;i = L[i].next;}// 倒数第二个结点指向-1L[j].next = -1;// 初始化最后一个结点L[i].data = '\0';L[i].next = -2;printf("删除成功!\n");}else{printf("插入失败! 链表为空!\n");}}else{printf("插入失败! 链表已销毁!\n");}
}

按位置删除

// 按位置删除
void LocateDelete(StaticList *L)
{if (L){int k;printf("请输入删除的数据位置:");scanf("%d", &k);if (k > 0 && L[0].next > 0){int i = 0, j = 0;// 查询第(j = k-1)个结点和第(i = k)个结点while ((k--) && L[i].next > 0){j = i;i = L[i].next;}if (k < 0){// 第(k-1)个结点指向第(k+1)个结点L[j].next = L[i].next;// 初始化第k个结点L[i].data = '\0';L[i].next = -2;printf("删除成功!\n");}else{printf("删除失败! 删除位置不合法!\n");}        }else{printf("删除失败! 链表为空!\n");}}else{printf("删除失败! 链表已销毁!\n");}
}

1.5 修改数据

// 修改链表
void ListModify(StaticList *L)
{if (L){int k;DataType x;printf("请输入需要修改的位置和修改后的数据:");scanf("%d %c", &k, &x);if (k > 0){ int index = 0;// 查询第i个结点位置while ((k--) && L[index].next > 0){index = L[index].next;} if (k < 0){L[index].data = x;printf("修改成功!\n");}else{printf("修改失败! 修改位置不合法!\n");}}else{printf("修改失败! 修改位置不合法!\n");}}else{printf("链表已销毁!\n");}
}

2. 源代码及测试

2.1 源代码

#include<stdio.h>
#include<stdlib.h>#define MaxSize 10typedef char DataType;
typedef struct LNode
{DataType data;int next;
}StaticList;void InitList(StaticList **L)
{// 为静态链表分配空间(*L) = (StaticList *)malloc(MaxSize * sizeof(StaticList));// 初始化StaticList *s = *L;s[0].data = '\0';s[0].next = -1;int i;for (i = 1; i < MaxSize; i++){s[i].data = '\0';s[i].next = -2;}printf("已初始化链表\n");
}// 查找空闲结点位置的下标
int GetFreeNodeIndex(StaticList *L)
{int i;for (i = 1; i < MaxSize; i++){        if (L[i].next == -2){return i;}}return 0;
}// 头部插入
void HeadInsert(StaticList *L)
{if (L){DataType x;printf("请输入插入的数据:");fflush(stdin);scanf("%c", &x);// 获取新结点的下标位置int free_node = GetFreeNodeIndex(L);if (free_node > 0){// 设置新结点的数据L[free_node].data = x;// 新结点指向链表的第一个结点L[free_node].next = L[0].next;// 头结点指向新结点,使得新结点成为链表的第一个结点L[0].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 链表空间已满!\n");}       }else{printf("插入失败! 链表已销毁!\n");}
}// 尾部插入
void TailInsert(StaticList *L)
{if (L){int i;DataType x;printf("请输入插入的数据:");fflush(stdin);scanf("%c", &x);int free_node = GetFreeNodeIndex(L);if (free_node > 0){int tail_index = 0;// 查找尾结点下标while (L[tail_index].next > 0){tail_index = L[tail_index].next;}// 设置新结点数据L[free_node].data = x;// 新结点指针域设置为空L[free_node].next = -1;//尾结点指向新结点,使得新结点成为链表的最后一个结点L[tail_index].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 链表空间已满\n");}}else{printf("插入失败! 链表已销毁!\n");}
}// 按位置插入
void LocateInsert(StaticList *L)
{if (L){int i, k;DataType x;printf("请输入插入的数据和插入位置:");scanf("%d %c", &k, &x);int free_node = GetFreeNodeIndex(L);if (k > 0 && free_node > 0){int insert_index = 0;// 查找链表中第(k-1)个结点while((--k) && L[insert_index].next > 0){   insert_index = L[insert_index].next;}// 插入新结点if (k == 0){// 设置新结点数据L[free_node].data = x;// 新结点指向第k个结点下标L[free_node].next = L[insert_index].next;// 第(k-1)个结点指向新结点L[insert_index].next = free_node;printf("插入成功!\n");}else{printf("插入失败! 插入位置不合法!\n");}}else{printf("插入失败! 插入位置不合法/链表空间已满!\n");}}else{printf("插入失败! 链表已销毁!\n");}
}// 头部删除
void HeadDelete(StaticList *L)
{if (L){if (L[0].next > 0){int first_index;// 获取第一个结点first_index = L[0].next;// 头结点指向第二个结点L[0].next = L[first_index].next;// 初始化第一个结点L[first_index].data = '\0';L[first_index].next = -2;printf("删除成功!\n");}else{printf("删除失败! 链表为空!\n");}}else{printf("删除失败! 链表已销毁!\n");}
}// 尾部删除
void TailDelete(StaticList *L)
{if (L){if (L[0].next > 0){int i = 0, j = 0;// 查询倒数第一个结点(i)和倒数第二个结点(j)while (L[i].next > 0){j = i;i = L[i].next;}// 倒数第二个结点指向-1L[j].next = -1;// 初始化最后一个结点L[i].data = '\0';L[i].next = -2;printf("删除成功!\n");}else{printf("插入失败! 链表为空!\n");}}else{printf("插入失败! 链表已销毁!\n");}
}// 按位置删除
void LocateDelete(StaticList *L)
{if (L){int k;printf("请输入删除的数据位置:");scanf("%d", &k);if (k > 0 && L[0].next > 0){int i = 0, j = 0;// 查询第(j = k-1)个结点和第(i = k)个结点while ((k--) && L[i].next > 0){j = i;i = L[i].next;}if (k < 0){// 第(k-1)个结点指向第(k+1)个结点L[j].next = L[i].next;// 初始化第k个结点L[i].data = '\0';L[i].next = -2;printf("删除成功!\n");}else{printf("删除失败! 删除位置不合法!\n");}        }else{printf("删除失败! 链表为空!\n");}}else{printf("删除失败! 链表已销毁!\n");}
}// 修改链表
void ListModify(StaticList *L)
{if (L){int k;DataType x;printf("请输入需要修改的位置和修改后的数据:");scanf("%d %c", &k, &x);if (k > 0){ int index = 0;// 查询第i个结点位置while ((k--) && L[index].next > 0){index = L[index].next;} if (k < 0){L[index].data = x;printf("修改成功!\n");}else{printf("修改失败! 修改位置不合法!\n");}}else{printf("修改失败! 修改位置不合法!\n");}}else{printf("链表已销毁!\n");}
}// 遍历链表
void DisplayList(StaticList *L)
{if (L){if (L[0].next > 0){int index = L[0].next;while(index > 0){printf("%c->", L[index].data);index = L[index].next;}printf("null\n");}else{printf("链表为空!\n");}    }else{printf("遍历失败! 链表已销毁!\n");}
}// 求链表长度
void ListLength(StaticList *L)
{if (L){int index = 0, length = 0;while (L[index].next > 0){length++;index = L[index].next;}printf("链表长度length = %d\n", length);}else{printf("链表已销毁!\n");}
}// 判断链表是否为空
void ListEmpty(StaticList *L)
{if (L){if (L[0].next > 0){printf("链表非空!\n");}else{printf("链表为空!\n");}}else{printf("链表已销毁!\n");}
}// 清空链表
void ClearList(StaticList *L)
{if (L){if (L[0].next > 0){int i = L[0].next, j = L[0].next;// 依次清除结点while (i > 0){// j:用于暂存下一个结点j = L[i].next;// 初始化结点iL[i].next = -2;// i:移动到下一个结点i = j;}L[0].next = -1;printf("链表已清空!\n");}else{printf("链表为空!\n");}   }else{printf("链表已销毁!\n");}
}// 销毁链表
void DestroyList(StaticList **L)
{free(*L);(*L) = NULL;printf("链表已销毁!\n");
}// 打印静态链表数组
void DisplayArr(StaticList *L)
{if (L){   int i;printf("***************************\n");printf("下标:\t");for (i = 0; i < MaxSize; i++){printf("%d\t", i);        }printf("\n数据域:\t");for (i = 0; i < MaxSize; i++){if (L[i].data){printf("%c\t", L[i].data);}else{printf("-\t");}}printf("\n指针域:\t");for (i = 0; i < MaxSize; i++){printf("%d\t", L[i].next);}printf("\n***************************\n");}else{printf("链表已销毁!\n");}
}int main()
{printf("*********************************\n");printf("其他 | 0:退出\t1:初始化\n");printf("插入 | 2:头插\t3:尾插\t4:按位插\n");printf("删除 | 5:头删\t6:尾删\t7:按位删\n");printf("查询 | 8:修改\t9:遍历\t10:求表长\n");printf("其他 | 11:表空\t12:清空\t13:销毁\n");printf("测试 | 14:打印静态链表数组\n");printf("*********************************\n");int k;StaticList *L;InitList(&L);while (1){printf("请输入操作序号:");scanf("%d", &k);if (!k){break;}switch (k){case 1:InitList(&L);    break;// 插入case 2:HeadInsert(L);  break;case 3:TailInsert(L); break;case 4:LocateInsert(L); break;// 删除case 5:HeadDelete(L);  break;case 6:TailDelete(L); break;case 7:LocateDelete(L);   break;// 查询case 8:ListModify(L);    break;case 9:DisplayList(L);    break;case 10:ListLength(L);    break;// 其他case 11:ListEmpty(L);    break;case 12:ClearList(L); break;case 13:DestroyList(&L);break;case 14:DisplayArr(L);  break;default:break;}printf("\n");}system("pause");return 0;
}

2.2 测试结果


数据结构_静态链表(C语言)相关推荐

  1. c语言将一个已知头结点的单链表逆序_C语言实现常用数据结构:静态链表数组实现(第5篇)...

    「今天是学习C语言第 148 天」 纸上学来终觉浅,绝知此事要躬行.-- 陆游「冬夜读书示子聿」 # 静态链表 使用数组实现,利用数组下标代替指针,从而实现数据结点之间的先后关系.实现要点: 1.数组 ...

  2. java静态链表_静态链表及其创建(C语言实现)

    <顺序表和链表优缺点>一节,我们了解了两种存储结构各自的特点,那么,是否存在一种存储结构,可以融合顺序表和链表各自的优点,从而既能快速访问元素,又能快速增加或删除数据元素. 静态链表,也是 ...

  3. 数据结构:静态链表实现树的同构

    写在最前面 按照课程讲解的思路来写,逻辑关系能够理解清楚了,但是实际运行起来实在是有问题,虽然在PTA上能够通过.但是我自己看不出问题来,并且,看了一遍又一遍仍然看不出来!(可能自己太笨..)这就说明 ...

  4. 数据结构 2-3-4 静态链表

    一.概念 静态链表相当于混合了数组和链表,单独的链表,使用next指针指向内存空间中下一个节点的位置来实现连接的,而数组中是用相对位置来实现,将二者混合,保留指向下一个的指针,但这个指针不是指针,而是 ...

  5. 数据结构_线索二叉树(C语言)

    数据结构总目录 线索二叉树 1. 结构解析 线索二叉树,是对链式二叉树中的空指针的再次利用,在一般的链式二叉树中,叶子结点都存在左右空指针,所以为了不浪费这些空指针,于是就有了线索二叉树. 线索二叉树 ...

  6. 数据结构_排序二叉树(C语言)

    数据结构总目录 排序二叉树 1. 结构解析 排序二叉树的结构规则很简单,只遵循一个基本规则: 那就是在二叉树中,选择任意根结点,其左子树都比根节点小,右子树都比根节点大. 排序二叉树结构图 观察如下二 ...

  7. 数据结构_分块查找(C语言)

    数据结构总目录 分块查找 分块查找又称索引顺序查找,这是一种性能介于顺序查找和折半查找之间的一种查找方法,也是顺序查找和折半查找的组合查找结合查找方法. 1. 图文解析 在分块查找中 (1)需要建立一 ...

  8. Scratch 与C语言实现数据结构静态链表的建立及操作

    Scratch 实现数据结构静态链表的建立及操作 scratch操作 Scratch 实现数据结构静态链表的建立及操作 数据结构 初始化静态链表 添加数据代码 删除数据 回收空闲节点操作代码 计算静态 ...

  9. 线性表详解(静态链表、单链表、双向链表、循环链表)

    目录 申明 1. 线性表的定义 2. 线性表的抽象数据类型 3. 线性表的顺序存储结构 3. 1 顺序存储定义 3. 2 顺序存储方式 3. 3 数据长度与线性表长度区别 3. 4 地址计算方法 4. ...

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

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

最新文章

  1. Django MTV模型思想
  2. 流程的python-流畅的Python
  3. 160个Crackme010
  4. HDFS High Availability体系介绍(Using the Quorum Journal Manager)
  5. 清华大学:全面如期开课,履行社会责任!
  6. MongoDB 定位 oplog 必须全表扫描吗?
  7. xposed hook 静态函数_浅谈 Xposed 新概念【模块作用域】
  8. SolidEdge 如何绘制局部视图 局部放大图
  9. mysql设置最大查询时间_mysql如何限制sql查询时间
  10. 随想录(搭建自己嵌入式项目的编译系统)
  11. java中多态案例工厂类,Java中构造器内部的多态方法的行为实例分析
  12. spring事务失效二:业务代码捕获异常
  13. 柯尼卡美能达一体机 扫描文件,不是全彩的,就首页和尾页是彩色,中间黑白
  14. MCTS人工智能围棋
  15. html手机端最小字体,移动端最小字体限制测试
  16. 实时分析:Flume+Kafka+SparkStreaming商品评分排行榜
  17. 讯时网关路由规则小结
  18. “decompose“没有适用于“ts“目标对象的方法
  19. MacBook电池使用策略
  20. ifconfig 使用

热门文章

  1. 安卓手机通话录音软件
  2. 虚拟机Ubuntut tftp服务不启动,service tftpd-hpa restart 失败的处理
  3. vue中el-calendar自定义日历控件
  4. 如何在计算机上设置禁止游戏,如何禁止玩电脑游戏 屏蔽网络游戏的方法
  5. 百度初级认证考试知识点
  6. MOSFET | 如何看懂MOSFET手册?①
  7. 隐马尔可夫模型简单理解
  8. 【微服务】什么是SOA服务架构?
  9. everthing 和 wox查找文件 文件夹 快速入门例子
  10. 【STM32】标准库 菜鸟入门教程(1)初识最小系统