C和指针 (pointers on C)——第十二章:利用结构和指针
第十二章 利用结构和指针
这章就是链表。先单链表,后双向链表。
总结:
单链表是一种使用指针来存储值的数据结构。链表中的每一个节点包括一个字段,用于指向链表的下一个节点。
有一个独立的根指针指向链表的第1个节点。
单链表仅仅能从一个方向遍历。
怎样insert单链表:1、新节点的link字段必须设置为指向它的后面节点。
2、前一个节点的link字段必须指向这个新节点。
为了防止可能会插入链表的起始位置这样的情况,在C中,能够保存一个指向必须进行改动的link字段的指针。而不是保存一个指向前一个节点的指针。
双链表中的每一个节点包括两个link字段:当中一个指向链表的下一个node。还有一个指向前一个node。
双链表有两个根指针,一个指向第一个node,还有一个指向最后一个node。因此遍历的过程中能够从不论什么一端開始。并且在遍历过程中够能够改变方向。
为了把一个新节点插入到双链表中。我们必须改动4个指针。新节点的前向和后向link字段必需被设置,前一个节点的fwd和后一个节点的bwd也要改动,指向新节点。
警告:
1、落到链表尾部的后面。
2、使用指针时应该格外小心。由于C并没有对他们的使用提供安全网。
3、从if语句中提炼语句可能会改变測试结果。
编程提示:
1、消除特殊情况使代码更易于维护。
2、不要轻易的进行提炼语句,这样会使你的语句更难维护。
编程实例:(本章就不再弄习题了,关于数据结构这块会有大量代码进行训练)
1、提炼后的单链表插入操作
- #include "stdlib.h"
- typedef struct NODE
- {
- struct NODE *link;
- int value;
- } Node;
- int sll_int(register Node **linkp, int new_value)
- {
- register Node *current; //指向当前节点
- register Node *new_node; //指向插入节点
- /*
- ** 寻找正确插入位置,按顺序訪问链表,直到有个值大于或等于新值
- */
- while ((current = current->link) != NULL && current->value < new_value)
- {
- linkp = ¤t->link; //移动linkp指向下一个Node的link
- }
- /* 分配新的内存,并存到新节点去 */
- new_node = (NODE *) malloc (sizeof(NODE));
- if (new_node == NULL)
- {
- return 0;
- }
- new_node->value = new_value;
- /* 插入新节点 */
- new_node->link = current;
- *linkp = new_node;
- return 1;
- }
2、双链表插入操作
- #include "stdlib.h"
- typedef struct NODE
- {
- struct NODE *fwd;
- struct NODE *bwd;
- int value;
- }Node;
- int dll_insert(Node *rootp, int value)
- {
- /* 把一个值插入到一个双向链表中。rootp是一个指向根节点的指针
- value 是插入的新值
- 返回值:假设已经存在链表中。返回0
- 假设内存不足导致无法插入,返回-1,成功返回1;
- */
- Node *this_node;
- Node *next_node;
- Node *new_node;
- for (this_node = rootp; next_node != NULL; this_node = next_node )
- {
- if (next_node->value == value)
- return 0;
- if (next_node->value < value)
- break;
- next_node = next_node->fwd;
- }
- /* 为新节点申请内存空间*/
- new_node = (Node *) malloc (sizeof(Node));
- if (new_node == NULL)
- return -1;
- new_node->value = value;
- /*
- 插入节点
- if 不在链表尾部 then 不在链表起始位置 or 位于链表起始位置
- else 在链表尾部 then 不在链表起始位置 or 位于链表起始位置(空链表)
- */
- if (next_node->fwd != NULL)
- {
- /*不在链表尾部*/
- if (this_node != rootp)
- {
- /* 不在链表的头部 */
- this_node->fwd = new_node;
- next_node->bwd = new_node;
- new_node->bwd = this_node;
- new_node->fwd = next_node;
- }
- else
- {
- /* 在链表的头部*/
- rootp->fwd = new_node;
- next_node->bwd = new_node;
- new_node->bwd = rootp;
- new_node->fwd = next_node;
- }
- }
- else
- {
- /*在链表尾部*/
- if (this_node->bwd != rootp)
- {
- /* 不在链表的头部 */
- new_node->fwd = NULL;
- new_node->bwd = this_node;
- this_node->fwd = new_node;
- rootp->bwd = new_node;
- }
- else
- {
- /* 在链表的头部*/
- new_node->fwd = NULL;
- new_node->bwd = NULL;
- rootp->bwd = new_node;
- rootp->fwd = new_node;
- }
- }
- }
版权声明:本文博客原创文章,博客,未经同意,不得转载。
C和指针 (pointers on C)——第十二章:利用结构和指针的更多相关文章
- C和指针 第十二章 使用结构和指针 双链表和语句提炼
双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...
- C和指针 第十二章 使用结构和指针
链表是一种常用的数据结构,每个节点通过链或者指针链接在一起,程序通过间接指针访问链表中的节点. typedef struct Node { //指向下一个节点的指针 struct Node *next ...
- 《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令
许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then ...
- perl5 第十二章 Perl5中的引用/指针
第十二章 Perl5中的引用/指针 by flamephoenix 一.引用简介二.使用引用三.使用反斜线(\)操作符四.引用和数组五.多维数组六.子程序的引用 子程序模板七.数组与子程序八.文件句 ...
- [CSAPP笔记][第十二章并发编程]
第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent).这种常见的现象称为并发(concurrency). 硬件异常处理程序,进程和Unix信号处理程序都是大家熟 ...
- C primer plus 第五版十二章习题
看完C prime plus(第五版)第十二章,随带完成了后面的习题. 1.不使用全局变量,重写程序清单12.4的程序. 先贴出12.4的程序,方便对照: /* global.c --- 使用外部变量 ...
- 《OpenCL异构并行编程实战》补充笔记散点,第五至十二章
▶ 第五章,OpenCL 的并发与执行模型 ● 内存对象与上下文相关而不是与设备相关.设备在不同设备之间的移动如下,如果 kernel 在第二个设备上运行,那么在第一个设备上产生的任何数据结果在第二个 ...
- 第十二章 Python文件操作【转】
12.1 open() open()函数作用是打开文件,返回一个文件对象. 用法格式:open(name[, mode[, buffering[,encoding]]]) -> file obj ...
- 【C++】《C++ Primer 》第十二章
第十二章 动态内存 目前为止,所使用的对象都有着严格定义的生存期. 全局对象在程序启动时分配,在程序结束时销毁.局部自动对象在进入其定义所在的程序块时被创建,在离开块时销毁.局部static对象在第一 ...
随机推荐
- (十二)RabbitMQ消息队列-性能测试
原文:(十二)RabbitMQ消息队列-性能测试 硬件配置 宿主机用的联想3850X6的服务器四颗E7-4850v3的处理器,DDR4内存,两块1.25TB的pcie固态.在宿主机上使用的事esxi5 ...
- [HTTP] Understand 2xx HTTP Status Code Responses
The 2xx family of status codes are used in HTTP responses to indicate success. Beyond the generic 20 ...
- Android中的消息机制:Handler消息传递机制 分类: H1_ANDROID 2013-10-27 22:54 1755人阅读 评论(0) 收藏
参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...
- Objective-C中 ==、isEqual、isEqualToString判断字符串相等
图片发自简书App 在判断一个字符串类型的变量是否与某字符时相等,你可能写下这样一行代码 if (activityType == @"0"){} //activityType是某一 ...
- 【45.65%】【codeforces 560B】Gerald is into Art
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- Java开发报表——Grid++Report 报表设计器
为了让数据显示的更加形象生动,报表在项目中差点儿是很常见的,可是大致能够分为两类: 一,图形:以图形的形式显示数据,比如柱状图,折线图,饼形图等等,这里有许多关于这方面的工具,比如JFreeChart ...
- PEM_密钥对生成与读取方法
PS:欢迎转载,但请注明出处,谢谢配合. 前言: PEM是OpenSSL和许多其他SSL工具的标准格式,OpenSSL 使用PEM 文件格式存储证书和密钥.这种格式被设计用来安全的包含在ascii甚至 ...
- oracle改动登录认证方式
通过配置sqlnet.ora文件.我们能够改动oracle登录认证方式. SQLNET.AUTHENTICATION_SERVICES=(NTS);基于操作系统的认证 SQLNET.AUTHENTIC ...
- 【u206】最大赢家
Time Limit: 1 second Memory Limit: 128 MB [问题描述] Nic和Susan在玩一个有趣的游戏:在游戏开始前,他们先约定一个正整数n,同时令m=1.游戏过程中, ...
- Android加载图片导致内存溢出(Out of Memory异常)
Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证) ...