C和指针 第十二章 使用结构和指针
链表是一种常用的数据结构,每个节点通过链或者指针链接在一起,程序通过间接指针访问链表中的节点。
typedef struct Node {
//指向下一个节点的指针
struct Node *next;
int value;
}
单链表只可以单向遍历
单链表中插入:第一版
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0 typedef struct Node {
struct Node *next;
int value;
} LinkList; //假设链表从小到大排序
int linkInsert(LinkList * current, int value)
{
//保存前一个节点
LinkList *previous;
LinkList *new; //循环到合适的位置
while (current-> value < value) {
previous = current;
current = current->next;
} new = malloc(sizeof(LinkList));
if (new == NULL) {
return FALSE;
} new->value = value;
new->next = current;
previous->next = new; return TRUE;
}
当插入值到表头和表尾时,会出错,需要加上对特殊情况的判断,将传入的第一个参数由,指向链表头部节点的指针改为,指向 指向链表头部的指针的指针,这样就可以添加节点到链表的头部。
添加特殊情况处理的版本二:
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0 typedef struct Node {
struct Node *next;
int value;
} LinkList; //
int linkInsert(LinkList **rootPtr, int value)
{
//保存前一个节点
LinkList *previous;
LinkList *current;
LinkList *new; current = *rootPtr;
previous = NULL; //循环到达末尾和找到符合要求的节点
while (current != NULL && current-> value < value) {
previous = current;
current = current->next;
} new = malloc(sizeof(LinkList));
if (new == NULL) {
return FALSE;
} new->value = value;
new->next = current; //指向列表首页
if(previous == NULL){
*rootPtr = new;
}else{
previous -> next = new;
} return TRUE;
} int main()
{
LinkList third = {NULL, 4};
LinkList second = {&third, 2};
LinkList first = {&second, 1};
LinkList *head = &first;
LinkList **rootPtr = &head; linkInsert(rootPtr, 0); LinkList *pre = NULL;
LinkList *current = *rootPtr;
while(current != NULL){
printf("%d\t", current -> value);
pre = current;
current = current -> next;
} return 0;
}
优化:
版本二把一个节点插入到链表的起始位置当做一种特殊情况处理,对于新节点需要修改的是根节点,对于其他任何点,修改的是前一个节点的next字段,其实这个两个修改是相同的,即修改指向当前节点的指针,所以当我们移动到下一个节点时,需要保存的是指向下一个节点的next字段的指针,而不是保持指向下一个节点的指针
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0 typedef struct Node {
struct Node *next;
int value;
} LinkList; //
int linkInsert(LinkList **nextPtr, int value)
{
LinkList *current;
LinkList *new; //nextPtr为指向当前节点的next字段的指针
while ((current = *nextPtr) != NULL && value > current -> value) {
nextPtr = ¤t -> next;
} new = malloc(sizeof(LinkList));
if (new == NULL) {
return FALSE;
} new-> value = value;
new-> next = current;
//前一个节点指向最新的节点,即使是表头也可以正常处理
*nextPtr = new; return TRUE;
} int main()
{
LinkList third = {NULL, 4};
LinkList second = {&third, 2};
LinkList first = {&second, 1};
//把head当做next字段,指向第一个节点
LinkList *head = &first;
LinkList **nextPtr = &head; linkInsert(nextPtr, 3); LinkList *current = *nextPtr;
while(current != NULL){
printf("%d\t", current -> value);
current = current -> next;
} return 0;
}
C和指针 第十二章 使用结构和指针的更多相关文章
- C和指针 第十二章 使用结构和指针 双链表和语句提炼
双链表中每个节点包含指向当前和之后节点的指针,插入节点到双链表中需要考虑四种情况: 1.插入到链表头部 2.插入到链表尾部 3.插入到空链表中 4.插入到链表内部 #include <stdio ...
- C和指针 第十二章 结构体 习题
12.3 重新编写12.7,使用头和尾指针分别以一个单独的指针传递给函数,而不是作为一个节点的一部分 #include <stdio.h> #include <stdlib.h> ...
- C和指针 第十二章 结构体 整体赋值 error: expected expression
定义结构体后整体赋值时发生错误 typedef struct NODE { struct NODE *fwd; struct NODE *bwd; int value; } Node; //声明变量 ...
- 《Linux命令行与shell脚本编程大全》第十二章 使用结构化命令
许多程序要就对shell脚本中的命令施加一些逻辑控制流程. 结构化命令允许你改变程序执行的顺序.不一定是依次进行的 12.1 使用if-then语句 如下格式: if command then ...
- C和指针 (pointers on C)——第十二章:利用结构和指针
第十二章 利用结构和指针 这章就是链表.先单链表,后双向链表. 总结: 单链表是一种使用指针来存储值的数据结构.链表中的每一个节点包括一个字段,用于指向链表的下一个节点. 有一个独立的根指针指向链表的 ...
- 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 在第二个设备上运行,那么在第一个设备上产生的任何数据结果在第二个 ...
随机推荐
- HashSet和TreeSet
package com.wzy.list; import java.util.HashSet; import java.util.Iterator; import java.util.Set; imp ...
- ListIterator接口,双向输出。
1,ListIterator接口与Itreator接口的区别. 2,使用限制. 定义如下: public interface ListIterator<E>extends Iterator ...
- Linux 进程间通讯详解二
消息队列 --消息队列提供了本机上从一个进程向另外一个进程发送一块数据的方法 --每个数据块都被认为有一个类型,接收者进程接收的数据块可以有不同的类型值 --消息队列也有管道一样的不足,就是每个消息的 ...
- WPF MVVM 验证
WPF MVVM(Caliburn.Micro) 数据验证 书接前文 前文中仅是WPF验证中的一种,我们暂且称之为View端的验证(因为其验证规是写在Xaml文件中的). 还有一种我们称之为Model ...
- 2016-2017-2 《Java程序设计》预备作业2总结
2016-2017-2 <Java程序设计>预备作业2总结 古希腊学者普罗塔戈说过:「头脑不是一个要被填满的容器,而是一束需要被点燃的火把.」 在对计算机系的学生情况的调查中,我说: 最近 ...
- C#进阶系列——DDD领域驱动设计初探(七):Web层的搭建
前言:好久没更新博客了,每天被该死的业务缠身,今天正好一个模块完成了,继续来完善我们的代码.之前的六篇完成了领域层.应用层.以及基础结构层的部分代码,这篇打算搭建下UI层的代码. DDD领域驱动设计初 ...
- 《Java EE 开发技术与案例教程》 这是一本好书啊:简洁精辟(相见恨晚)
第一章:Java EE 概述 1.get:JPA:Java Persistence API, 数据持久化API: JPA是一种ORM规范,它的实现实例:Hibernate.mybatis 2.Web ...
- jeecg单步调试
自己没本事写开发平台,用别人的又各种担心,想学着别人弄个单步调试,老是出现这个"source not found"-- 百度各种方法都搞不定,担心是自己安装错了?这个jeecg本身 ...
- [webpack] webpack-dev-server介绍及配置
webpack-dev-server是webpack官方提供的一个小型Express服务器.使用它可以为webpack打包生成的资源文件提供web服务.webpack-dev-server官方文档 w ...
- 【USACO 2.4】Fractions to Decimals(分数转小数)
题意:给你N/D的分数,让你输出等价的小数,如果是循环小数,用括号把循环节包起来.如果是整数,后面保留一位小数.每行最多输出76个字符. 题解:模拟除法,如果余数是第二次出现,则代表第一次出现的位置到 ...