typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList;

带头结点的按位序插入:

//在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, char e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
} if (p == NULL) //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode)); //新结点
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

不带头结点的按位序插入:(对于插入第一个结点时需要特殊处理,其他部分与带头结点的一样)

bool ListInsert(LinkList &L, int i, char e) {
if (i == ) {
LNode *s = (LNode *)malloc(sizeof(LNode));
s->data = e;
s->next = L;
L = s;
return true
}
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
} if (p == NULL) //i值不合法(最后一个结点指向NULL,这是要在NULL的后边插入)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode)); //新结点
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

指定结点的后插操作:

//在p结点之后插入元素e
bool InsertNextNode(LNode *p, char e) {
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
return false; //内存分配失败
s->data = e;
s->next = p->next;
p->next = s;
return true;
}

这里的后插操作其实就相当于已经找到了p,和按位序插入while循环后边的代码一样了,所以按位序插入后边部分可以调用这个函数:

//在第i个位置插入元素e
bool ListInsert(LinkList &L, int i, char e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) { //循环找到要插入结点的前一个结点
p = p->next;
j++;
}
  return InsertNextNode(p,e)
}

指定结点的前插操作:

如果给了头指针的话,只需要循环查找到要插入结点的前一个结点,然后插入即可

//在p结点之前插入元素e
bool InsertPriorNode(LinkList L, LNode *p, char e)

然而如果不给头指针的话,就需要偷天换日一下,把新结点插入到p结点后边,然后把新结点的数据元素和和p结点互换,逻辑上实现同样的效果

//在p结点之前插入元素e
bool InsertPriorNode(LNode *p, char e) {
if (p == NULL)
return false;
LNode *s = (LNode *)malloc(sizeof(LNode));
if (s == NULL)
return false; //内存分配失败
s->next = p->next;
p->next = s;
s->data = p->data;
p->data = e;
return true;
}

如果是直接传入了结点s,道理是一样的;

//在p结点之前插入结点s
bool InsertPriorNode(LNode *p, LNode *s) {
if (p == NULL || s == NULL)
return false;
s->next = p->next;
p->next = s;
char temp = p->data;
p->data = s->data;
s->data = temp;
return true;
}

按位序删除(带头结点):

前半部分与插入结点一样,先循环查找p

//删除表L中第i个位置的元素,并用e返回删除元素的值
bool ListDelete(LinkList &L, int i, char &e) {
if (i < )
return false; LNode *p; //p指向当前扫描到的结点
int j = ; //当前p指向的是第几个结点
p = L; //L指向头结点,第0个结点
while (p != NULL && j < i - ) {
p = p->next;
j++;
} if (p == NULL)
return false;
if (p->next == NULL)
return false;
LNode *q = p->next; //令q指向被删除的结点
e = q->data; //用e返回被删的值
p->next = q->next; //断开连接
free(q); //释放被删结点空间
return true;
}

指定结点的删除:

删除结点p,需要修改其前驱 结点的next指针
方法1:传入头指针,循环寻找p的前驱结点

方法2:偷天换日(类似于结点前插的实现)

下面是方法2的代码实现:

//删除指定结点p
bool DeleteNode(LNode *p) {
if (p == NULL)
return false;
LNode *q = p->next; //令q指向*p的后继结点
p->data = p->next->data;
p->next = q->next;
free(q);
return true;
}

如果p是最后一个结点就只能从表头开始依次寻找p的前驱...

DS-4-单链表的各种插入与删除的实现的更多相关文章

  1. Python实现单链表数据的添加、删除、插入操作

    Python实现单链表数据的添加.删除.插入操作 链表的定义: 链表(linked list)是由一组被称为结点的数据元素组成的数据结构,每个结点都包含结点本身的信息和指向下一个结点的地址.由于每个结 ...

  2. C语言习题 链表建立,插入,删除,输出

    Problem B: C语言习题 链表建立,插入,删除,输出 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 222  Solved: 92 [Subm ...

  3. SDUT OJ 数据结构实验之链表七:单链表中重复元素的删除

    数据结构实验之链表七:单链表中重复元素的删除 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem ...

  4. YTU 2430: C语言习题 链表建立,插入,删除,输出

    2430: C语言习题 链表建立,插入,删除,输出 时间限制: 1 Sec  内存限制: 128 MB 提交: 576  解决: 280 题目描述 编写一个函数creatlink,用来建立一个动态链表 ...

  5. SDUT-2122_数据结构实验之链表七:单链表中重复元素的删除

    数据结构实验之链表七:单链表中重复元素的删除 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 按照数据输入的相反顺序(逆 ...

  6. C语言双链表遍历,插入,删除

    #include<stdio.h> #include<stdlib.h> #include <string.h> #define bzero(a, b) memse ...

  7. Problem A: C语言习题 链表建立,插入,删除,输出

    #include<stdio.h> #include<string.h> #include<stdlib.h> typedef struct student { l ...

  8. 数据结构实验之链表七:单链表中重复元素的删除(SDUT 2122)

    #include <bits/stdc++.h> using namespace std; typedef struct node { int data; struct node* nex ...

  9. 单链表的插入删除操作(c++实现)

    下列代码实现的是单链表的按序插入.链表元素的删除.链表的输出 // mylink.h 代码 #ifndef MYLINK_H #define MYLINK_H #include<iostream ...

随机推荐

  1. 【Java】手把手模拟CAS,瞬间理解CAS的机制

    话不多少,先看个案例,[模拟100个用户,每个用户访问10次网站]”: public class ThreadDemo1 { //总访问量 ; //模拟访问的方法 public static void ...

  2. 29-3 union的使用

    联合结果集union (集合运算符) -------------------------使用union联合结果集---------------- select tsname,tsgender,tsag ...

  3. LoadBalancer在kubernetes架构下的实践

    Backgound 借助于kubernetes优秀的弹性扩缩功能,运行其中的应用程序能够在流量突增的时候坦然应对,在流量低谷的时候无需担心成本.但于此同时,也带来了极大的挑战: 弹性扩缩导致容器IP动 ...

  4. Blazor WebAssembly 候选版迁移手记

    前言 之前我写过一篇关于 Blazor WebAssembly 的文章浏览器中的 .Net Core —— Blazor WebAssembly 初体验,如今已经更新到 RC-1,与预览版有着较大的差 ...

  5. 01 . RabbitMQ简介及部署

    RabbitMQ简介 ​ MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它 ...

  6. GitHub 热点速览 Vol.22:如何打造超级技术栈

    作者:HelloGitHub-小鱼干 摘要:build-your-own-x,无论是新手还是老手,这都是一个指向标.方向有了,剩下就是时间和实践的事情,收集了大量可用于软件和 Web 开发的 Publ ...

  7. Cypress系列(6)- Cypress 的重试机制

    如果想从头学起Cypress,可以看下面的系列文章哦 https://www.cnblogs.com/poloyy/category/1768839.html 前言 重试(Retry-ability) ...

  8. 【Hadoop】hdfs的秘密,namenode,datanode,yarn,安全模式,fsimage,edits...

    1.bin/hdfs namenode -format ** 注意事项 1.在配置好了配置文件之后,首次启动之前,做初始化操作 2.在后续启动的时候,不需要再初始化 3.初始化的一些影响 一.初始化操 ...

  9. java方法句柄-----2.方法句柄的获取、变换、特殊方法句柄

    目录 1.获取方法句柄 1.1查找构造方法.一般方法和静态方法的方法句柄 1.2 查找类中的特殊方法(类中的私有方法) 1.3 查找类中静态域和一般域 1.4 通过反射API得到的Constructo ...

  10. Linux(十) —— 使用 rz 和 sz 命令上传与下载

    以CentOS 7 系统为例,一般上传下载都是使用的第三方工具,但是在操作上并不方便,每次都要找到对应的目录才可以执行上传.下载操作,比较麻烦. 而CentOS为例的 Linux 系统可以通过安装 插 ...