4-双链表的操作

1.定义一个双链表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int ElemType;/* 定义一个单链表 */
typedef struct DNode {/*数据域*/ElemType data;/*前驱指针域*/struct LNode *prior;/*后驱指针域*/struct LNode *next;
} DNode, *DinkList; /*DNode处理单个节点 ; DinkList处理整个双链表*/int main() {return 0;
}

插入和删除双链表

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int ElemType;/* 定义一个双链表节点 */
typedef struct DNode {ElemType data;            /* 数据域 */struct DNode *prior;      /* 前驱指针域 */struct DNode *next;       /* 后驱指针域 */
} DNode, *DLinkList;/* 初始化双链表 */
DLinkList initDLinkList() {DLinkList L = (DLinkList ) malloc(sizeof(DNode));if (L == NULL) {printf("内存分配失败\n");exit(1);}L->next = NULL;L->prior = NULL;return L;
}/* 获取双链表长度 */
int length(DLinkList L) {int len = 0;DNode *p = L->next; // 假设L是一个头节点while (p != NULL) {len++;p = p->next;}return len;
}/* 按位查找,返回第i个位置的节点指针 */
DNode* getElemByPos(DLinkList L, int i) {int j = 0;DNode *p = L;while (p != NULL && j < i) {p = p->next;j++;}return p;
}/* 在双链表的第i个位置插入元素值为x的节点 */
void insertNode(DLinkList L, int i, ElemType x) {if (i < 1 || i > length(L) + 1) {printf("无效的位置\n");return;}DNode *p = getElemByPos(L, i - 1);/*定义一个要插入的节点指针*/DNode *s = (DNode *) malloc(sizeof(DNode));if (s == NULL) {printf("内存分配失败\n");exit(1);}/*修改s地址上的实际 的值*/s->data = x;/**/s->next = p->next;if (p->next != NULL) {/*当我们插入新节点 s 后,需要确保新节点 s 成为原来第 i 个节点的前驱节点,因此我们将 p->next->prior 设置为 s。更详细的解释:新节点 s 将插入到 p 之后,成为新的第 i 个节点。原来的第 i 个节点的前驱节点将更新为新节点 s。*/p->next->prior = s;/*p->next->prior = s;可以改写为:如下代码*///先获取原来i位置上的地址指针 (p->next)// 原来i位置上的地址指针  变为了 i+1 的位置/*所有  原来i位置上的地址指针的前驱指针域prior 变成了新插入的指针s 的地址*///(p->next)->prior=s;}s->prior = p;p->next = s;
}/* 删除双链表中第i个位置的节点 */
bool deleteNode(DLinkList L, int i, ElemType *e) {if (i < 1 || i > length(L)) {return false;}/*获取 i-1 位序上的节点地址 */DNode *p = getElemByPos(L, i - 1);/*获取要删除的节点的地址*/DNode *q = p->next;if (q == NULL) {return false;}/*更新 i-1 的后驱指针域 为 i+1的地址指针*/p->next = q->next;if (q->next != NULL) {q->next->prior = p;}*e = q->data;/*删除q指针*/free(q);return true;
}int main() {/* 初始化双链表L为一个带头节点的空链表 */DLinkList L = initDLinkList();/* 插入测试数据 */insertNode(L, 1, 10); // 在第1个位置插入10insertNode(L, 2, 20); // 在第2个位置插入20insertNode(L, 1, 5);  // 在第1个位置插入5/* 打印链表 */DNode *p = L->next;while (p != NULL) {printf("%d -> ", p->data);p = p->next;}printf("NULL\n");/* 删除节点测试 */ElemType e;if (deleteNode(L, 2, &e)) {printf("已删除节点的值: %d\n", e);} else {printf("删除失败\n");}/* 再次打印链表 */p = L->next;while (p != NULL) {printf("%d -> ", p->data);p = p->next;}printf("NULL\n");/* 释放链表 */p = L;while (p != NULL) {DNode *temp = p;p = p->next;free(temp);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/740044.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 字符串拼接原理

原文:Java 字符串拼接原理我们知道 Java 可以直接使用加号+来拼接字符串。 字符串+拼接的本质是使用StringBuilder.append()(已在Java8测试通过),最终如果要赋值给字符串变量时,会调用toString()。 /*** 字符串追加*/ @Test public void testStrAppend() {/** + 之前先隐式…

scope-sentry-数据泄露规则提取

工具简述 Scope Sentry是一款具有资产测绘、子域名枚举、信息泄露检测、漏洞扫描、目录扫描、子域名接管、爬虫、页面监控功能的工具,通过构建多个节点,自由选择节点运行扫描任务。当出现新漏洞时可以快速排查关注资产是否存在相关组件。 对该工具分析主要是分析内部的信息泄…

es8.x 版本使用及 java api client

1.为什么不使用High Level REST Client 了 那在 ElasticSearch 7.15.0 版本开始,官方又不建议使用 High Level REST Client 了,为什么呢?因为它是基于原生的 REST API,而这些 API 在某些情况下限制了某些功能的性能优化。与此同时,官方也推出了 Elasticsearch Java 客户端…

7.7-DPday1

动态规划理论基础什么是动态规划 动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。 所以动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的 在关于贪心…

gitlab私有仓库搭建

安全:关闭防火墙,selinux 1.安装GItlab所需的依赖包 yum install curl policycoreutils-python openssh-server postfix wget -y安装gitlab 获取gitlab源码包 选择各种yum源去安装 https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.0.3-ce.0.el7.x86_64…

[LeetCode] 134. Gas Station

想到了提前判断和小于0的情况,懒得写,果然被阴间用例10万个加油站坑了。 class Solution:def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:#1n = len(gas)if n ==1:if gas[0] >= cost[0]:return 0else:return -1#-1startpoint =[gas[x] - cost[…

算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」不要轻易使用 For 循环 For 循环,老铁们在编程中经常用到的一个基本结构,特别是在处理列表、字典这类数据结构时。但是,这东西真的是个双刃剑。虽然看起来挺直白,一…

(三)变分自动编码器

过去虽然没有细看,但印象里一直觉得变分自编码器(Variational Auto-Encoder,VAE)是个好东西。于是趁着最近看概率图模型的三分钟热度,我决定也争取把VAE搞懂。于是乎照样翻了网上很多资料,无一例外发现都很含糊,主要的感觉是公式写了一大通,还是迷迷糊糊的,最后好不容…

大气热力学(8)——热力学图的应用之一

本篇文章源自我在 2021 年暑假自学大气物理相关知识时手写的笔记,现转化为电子版本以作存档。相较于手写笔记,电子版的部分内容有补充和修改。笔记内容大部分为公式的推导过程。 目录8.1 复习斜 T-lnP 图上的几种线8.1.1 等温线和等压线8.1.2 干绝热线8.1.3 湿绝热线8.1.4 等…

(二)变分贝叶斯

变分 对于普通的函数f(x),我们可以认为f是一个关于x的一个实数算子,其作用是将实数x映射到实数f(x)。那么类比这种模式,假设存在函数算子F,它是关于f(x)的函数算子,可以将f(x)映射成实数F(f(x)) 。对于f(x)我们是通过改变x来求出f(x)的极值,而在变分中这个x会被替换成一个…

03-码出高效:Java开发手册.pdf

03-码出高效:Java开发手册.pdf 03-码出高效:Java开发手册.pdf ​​ ​​ ‍ ​​ ‍ ‍