算法2.8:单链表中插入一个节点

下面是书中的伪代码:

Status ListInsert_L(LinkList &L, int i, ElemType e) { // 在带头结点的单链线性表L的第i个元素之前插入元素eLinkList p,s;p = L;   int j = 0;while (p && j < i-1) {  // 寻找第i-1个结点p = p->next;++j;} if (!p || j > i-1) return ERROR;      // i小于1或者大于表长s = (LinkList)malloc(sizeof(LNode));  // 生成新结点s->data = e;  s->next = p->next;      // 插入L中p->next = s;return OK;
} // LinstInsert_L

下面我们来分析下:

1.第一行是Status表示一种状态,因为C语言里面没有泛型,所以用这个表示。

2.这里的LinkList是*LinkList(书上对这个有定义,在本博客中不再说明)。

3.这里如果LinkList &L,是一个链表,这个p指向了L的地址。这样的话当while循环结束后,那么p就是指向第i-1个元素的地址。

4.s在堆中开辟了一个LNode大小的空间,并且把e赋值给了s->data。

5.插入时我们要注意,先把p->next给s->next(就是先连s后继,如果先连接p的后继话这个链表是不能连起来的,大家可以试试),然后在连接p的后继。

算法2.9:带头结点的链表的删除

下面是书中的伪代码:

Status ListDelete_L(LinkList &L, int i, ElemType &e) { // 在带头结点的单链线性表L中,删除第i个元素,并由e返回其值LinkList p,q;p = L;int j = 0;while (p->next && j < i-1) {  // 寻找第i个结点,并令p指向其前趋p = p->next;++j;}if (!(p->next) || j > i-1) return ERROR;  // 删除位置不合理q = p->next;p->next = q->next;           // 删除并释放结点e = q->data;free(q);return OK;
} // ListDelete_L

下面是思路:

这个程序比较简单,我们讲解下思路就可以了。先用p指向要删除的LinkList的前面那个元素,用q指向p后面那个元素(也就是要删除的元素),把q->next赋值各p->next,这样的化就把q隔离出来了,最后在free就可以了。这个比较简单。

算法2.10:创建带头结点的单链表。

下面是书中的伪代码:

void CreateList_L(LinkList &L, int n) { // 逆位序输入(随机产生)n个元素的值,建立带表头结点的单链线性表L LinkList p;int i;L = (LinkList)malloc(sizeof(LNode));L->next = NULL;              // 先建立一个带头结点的单链表for (i=n; i>0; --i) {p = (LinkList)malloc(sizeof(LNode));  // 生成新结点p->data = random(200);     // 改为一个随机生成的数字(200以内)p->next = L->next;    L->next = p;    // 插入到表头}
} // CreateList_L

下面是思路:

1.带头结点的链表是指,链表里面的第一个结点,不存数据。

2.这里的i是要包含除头结点外的还有多少个节点。

3.这里的random函数是产生随机种子,他在头文件#include<stdlib.h>中,大小为0~199。

4这里是在表头中不停的插入,而不是在表尾中插入。

算法2.11:

如何将两个有序链表并为一个有序链表。

下面是伪代码:

void MergeList_L(LinkList &La, LinkList &Lb, LinkList &Lc) {// 已知单链线性表La和Lb的元素按值非递减排列。// 归并La和Lb得到新的单链线性表Lc,Lc的元素也按值非递减排列。LinkList pa, pb, pc;pa = La->next;    pb = Lb->next;Lc = pc = La;             // 用La的头结点作为Lc的头结点while (pa && pb) {if (pa->data <= pb->data) {pc->next = pa;   pc = pa;   pa = pa->next;}else { pc->next = pb;   pc = pb;   pb = pb->next; }}pc->next = pa ? pa : pb;  // 插入剩余段free(Lb);                 // 释放Lb的头结点
} // MergeList_L

下面我们来分析下:

1.这个程序是思路是,用三个LinkList,pa,pb.pc分别指向La,Lb的第一个元素Lc的头结点,然后比较,pa->data,和pb->data的值,谁下就把谁放入pc,然后指针后移,在最后,把还剩下的那个链的部分,直接接到pc。

2.这伪代码有个问题,也就是最后的free(Lb),如果要清理,也要加上free(La)才行。

3.这个例子的巧妙之处在于只需将原来两个链表中节点之间的关系解除,程序按元素非递减的关系将所有节点链接成一个链表即可。

算法2.12:

在静态链线性表L中查找第1个值为e的元素

下面是伪代码:

int LocateElem_SL(SLinkList S, ElemType e) { // 在静态单链线性表L中查找第1个值为e的元素。// 若找到,则返回它在L中的位序,否则返回0。int i;i = S[0].cur;                              // i指示表中第一个结点while (i && S[i].data != e) i = S[i].cur;  // 在表中顺链查找return i;
} // LocateElem_SL

下面我们来分析下:

1.静态链表:在不设置“指针”类型的高级程序设计语言中使用的,需要预先分配一个较大的空间。

2.这个程序的思路是:cur是一个指示器类似于next,如下图所示,相信看了下图,就能理解,下图是插入数据元素SHI和删除数据元素ZHENG

3.这个cur存的是下标(因为这是SLinkList[MAXSIZE])。

4.最后返回数组下标的值。

算法2.13:

在静态链中将所有未被使用过以及被删除的分量用游标链成一个备用的链表,每当进行插入时便可从备用链表上取得第一个结点作为待插入点;反之,在删除时将此元素插入S表

下面以(A-B)U(B-A)=(AUB)-(A∩B)为例子。

假设由终端输入集合元素,先建立表示集合A的静态链表S,从而在输入集合B的元素的同时查找S表,若存在和B相同的元素,则从S表删除,否则插入S表。

算法2.13功能:将整个数组空间初始化成一个链表。

算法2.14功能:从备用空间取得一个结点。

算法2.15功能:将空间节点链结到备用链表上。

算法2.16功能:完整功能实现

下面是伪代码:

void InitSpace_SL(SLinkList space) {// 将一维数组space中各分量链成一个备用链表,space[0].cur为头指针,// "0"表示空指针for (int i=0; i<MAXSIZE-1; ++i)  space[i].cur = i+1;space[MAXSIZE-1].cur = 0;
} // InitSpace_SL

下面来分析下:

1.init的全写为initialization,意思为初始化。

2.这个程序的最后是space[MAXSIZE-1].cur=0;是把这个静态链头尾相连变成一个环。

算法2.14:从备用空间取得一个结点。

下面是代码:

int Malloc_SL(SLinkList &space) { // 若备用空间链表非空,则返回分配的结点下标,否则返回0int i = space[0].cur;if (space[0].cur) space[0].cur = space[space[0].cur].cur;return i;
} // Malloc_SL

下面我们来分析下代码:

1.malloc的全称为mallocate,意思是分配。

2.这个程序是首先得到下标为0的链表对应的cur,当下标为0的cur不为0时,说明非空,则把space[0].cur这个是数提出来,再把这个数组对应的下标赋值给0对应的下标。

3.不懂的同学,带几个数进去就懂了。

算法2.15:将空间节点链结到备用链表上

下面是伪代码:

void Free_SL(SLinkList &space, int k) {// 将下标为k的空闲结点回收到备用链表space[k].cur = space[0].cur;    space[0].cur = k;
} // Free_SL

下面我们来分析下:

这个是先把以前0的下标给后数组第k行对应的下标,然后到数组0下标改为k。

算法2.16:完整功能实现

下面是伪代码:

void difference(SLinkList &space, int &S) {// 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A)// 的静态链表, S为头指针。假设备用空间足够大,space[0].cur为头指针。int i, j, k, m, n, p, r;ElemType b;InitSpace_SL(space);          // 初始化备用空间S = Malloc_SL(space);         // 生成S的头结点r = S;                        // r指向S的当前最后结点m = random(2,8);              // 输入A的元素个数n = random(2,8);              // 输入B的元素个数printf("  A = ( ");initrandom_c1();for (j=1; j<=m; ++j) {        // 建立集合A的链表i = Malloc_SL(space);      // 分配结点//printf("i=%d   ",i);space[i].data = random_next_c1();   // 输入A的元素值printf("%c ", space[i].data);       // 输出A的元素space[r].cur = i;  r = i;  // 插入到表尾}printf(")\n");space[r].cur = 0;             // 尾结点的指针为空initrandom_c1();printf("  B = ( ");for (j=1; j<=n; ++j) {// 依次输入B的元素,若不在当前表中,则插入,否则删除b = random_next_c1();       // 输入B的元素值printf("%c ", b);           // 输出B的元素p = S;   k = space[S].cur;  // k指向集合A中第一个结点while (k!=space[r].cur && space[k].data!=b) {// 在当前表中查找p = k;    k = space[k].cur;}if (k == space[r].cur) {// 当前表中不存在该元素,插入在r所指结点之后,且r的位置不变i = Malloc_SL(space);space[i].data = b;space[i].cur = space[r].cur;space[r].cur = i;} else {                     // 该元素已在表中,删除之space[p].cur = space[k].cur;Free_SL(space, k);if (r == k)  r = p;      // 若删除的是尾元素,则需修改尾指针}}printf(")\n");
} // difference

下面我们来分析一下:

1.这里面用产生了两个随机种子赋值给了m和n。

2.这里的random_next_c1();函数估计就是参数一个随机字符。

3.第一个for循环结束后把space里面下标为1-m的数都赋值了。

4.第二个for循环里面的while循环,是判断是否有相同的数,和是不是检索完了数组。

假设A=(c,b,e,g,f,d),B=(a,b,n,f)则,这图很好的表示了此算法:

2.3线性表的链式表示和实现相关推荐

  1. 数据结构和算法:(3)3.2线性表的链式存储结构

    线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素也就是说你这个可以放在A地点,这个可以放在E地点,A地点和E地点中间可以隔开一个C地点和D地点,这样是允许的),这组存储单元可以存在 ...

  2. 带头结点的线性表的链式实现

    复习了顺序实现后,自己模仿着写了链式实现 /*** @author lirui 带头结点的线性表的链式实现*/ public class MyLinkList<T> {// 内部类LNod ...

  3. 链表list(链式存储结构实现)_5 线性表的链式存储结构

    系列文章参考资料为<大话数据结构>,源码为个人私有,未经允许不得转载 线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素,可以使连续的,也可以不连续,也就意味这些元素可以 ...

  4. JAVA数据结构 线性表的链式存储及其实现

    2019独角兽企业重金招聘Python工程师标准>>> 2线性表的链式存储及其实现 虽然顺序表具有随机存取的特点是一种有用的存储结构但是也有缺陷: (1)      若需要给顺序表增 ...

  5. 线性表的链式表示——单链表

    单链表 定义 线性表的链式存储又称单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素.每个链表的结点,除存放元素自身的信息之外,还需要存放一个指向其后继结点的指针.即单链表的结构分为两部分, ...

  6. 五、【线性表】线性表的链式表示和实现

    线性表的链式表示和实现 上节提到,由于顺序表的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素.然而,这也导致了顺序表在执行插入或删除操作时,需要移动大量元素.本节来讨论 ...

  7. 从零开始学数据结构和算法(二)线性表的链式存储结构

    链表 链式存储结构 定义 线性表的链式存储结构的特点是用一组任意的存储单元的存储线性表的数据元素,这组存储单元是可以连续的,也可以是不连续的. 种类 结构图 单链表 应用:MessageQueue 插 ...

  8. C和C++线性表的链式存储

    C和C++线性表的链式存储 基本概念 链表技术领域推演 设计与实现 重要技术场景图 链表链式存储_插入 链表链式存储_删除 优点和缺点 基本概念 链式存储定义 为了表示每个数据元素与其直接后继元素之间 ...

  9. 【数据结构】线性表的链式存储-单链表

    单链表的定义 线性表的链式存储又称为单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素. 为了建立起数据元素之间的线性关系,对每个链表结点,除了存放元素自身的信息之外,还需要存放一个指向其后 ...

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

    线性表的定义 线性表是具有相同数据类型的n(n >= 0)个数据元素的有限序列.其中n为表长,当n = 0时,该线性表是一个空表.若用L命名线性表,其一般表示为:L = (a1, a2, ... ...

最新文章

  1. ElasticSearch-hadoop saveToEs源码分析
  2. UA PHYS515A 电磁理论II 静电学问题的一个例子
  3. 计算机存有多少游戏,8G和16G的计算机内存之间有很大区别吗?玩游戏需要多少内存?...
  4. JAVA的DES加密解密在windows上测试一切正常,在linux上异常
  5. Atitit git push 报错 remote: error: hook declined to update git push 报错 remote: error: hook declined
  6. plc比c语言还难,plc编程好学吗??
  7. delphi 2010 mysql_Delphi2010 DBExpress+MySQL 程序的打包
  8. java核心技术卷1基础知识整理
  9. 环境土壤物理模型HYDRUS1D/2D/3D实践技术
  10. 晶体管开关电路的设计以及如何提高其开关速度
  11. Some Laws in IT
  12. Spring Framework究竟是什么? [关闭]
  13. 使用JavaCV把图片合成视频(实用)
  14. 打印系统开发(63)——C# 实现虚拟打印机 HP Color LaserJet 4500 (2) True Type Font字体显示
  15. 倍福PLC获取伺服驱动器扭矩值获取电流值
  16. Python_爬虫_中文乱码
  17. 七种常见阈值分割代码(Otsu、最大熵、迭代法、自适应阀值、手动、迭代法、基本全局阈值法)...
  18. FileZilla使用密钥文件连接linux服务器上传文件
  19. 数据结构之排序(Sort)
  20. oracle11完全卸载

热门文章

  1. 15 道超经典大厂 Java 面试题!重中之重
  2. 某一个物种能够在 1 分钟之内干掉资深程序员...网友称:恐怖如斯!
  3. 今天的西红柿就跑了的P8U8源码
  4. 一个简单的录音软件程序代码【C++】
  5. 代码写累了来这看看,笑笑
  6. 一步步Notepad变Word
  7. 盘点黑客与程序员的十大区别
  8. 我是如何走上前端开发这条路 并常年保持一线竞争力的
  9. React Native 宣布重构计划!
  10. 程序员工资虽高,但日子过得....