《Redis设计与实现》知识点目录
Redis设计与实现
第一部分 数据结构与对象
第二章 简单动态字符串
- p8 简单动态字符串SDS
2.1 SDS的定义
- p9 每个sds.h/sdshdr结构表示一个SDS值
2.2 SDS与C字符串的区别
- p10 常数复杂度获取字符串长度
- p10 获取一个SDS长度的复杂度仅为O(1)
- p11 杜绝缓冲区溢出
- p11 SDS修改操作
- p12 减少修改字符串带来的内存重分配次数
- p13 空间预分配
- p14 惰性空间释放
- p15 二进制安全
- p16 SDS的二进制安全
- p16 兼容部分C字符串函数
- p17 SDS可以在有需要时重用<String.h>函数库
- p17 总结
- p17 C字符串和SDS之间的区别
2.3 SDS API
- P17 SDS的主要操作API
2.4 重点回顾
- p18 SDS相比C字符串的优点
第三章 链表
3.1 链表和链表节点的实现
- p20 list结构
- p21 Redis链表的实现特性
3.2 链表和链表节点的API
- p21 用于操作链表和链表节点的API
3.3 重点回顾
第四章 字典
4.1 字典的实现
p24 哈希表
- p24 dictht结构
p25 哈希表节点
- p25 dictEntry结构
p26 字典
- p26 dic结构
4.2 哈希算法
- p27 Redis计算哈希值和索引值的方法
- p28 Redis使用MurmurHash2算法计算键的哈希值
4.3 解决键冲突
- p28 Redis的哈希表使用链地址法解决键冲突
4.4 rehash
- p29 Redis对字典的哈希表执行rehash的步骤如下
- p32 哈希表的扩展与收缩
- p32 负载因子
4.5 渐进式rehash
- p33 渐进式rehash详细步骤
- p36 渐进式rehash执行期间的哈希表操作
4.6 字典API
- p36 字典的主要操作API
第五章 跳跃表
- p38 跳跃表
5.1 跳跃表的实现
p39 跳跃表由zskiplistNode和zskiplist两个结构定义
p39 zskiplist结构
p40 跳跃表节点
- p40 zskiplistNode结构
- p40 层
- p40 前进指针
- p41 跨度
- p42 后退指针
- p42 分值和成员
- p43 跳跃表
- p40 zskiplistNode结构
5.2 跳跃表API
- p44 跳跃表的所有操作API
第六章 整数集合
6.1 整数集合的实现
- p47 contents数组(整数集合底层实现)的真正类型取决于encoding的值
6.2 升级
- p48 升级整数集合并添加新元素的三步骤
- p50 升级之后新元素的摆放位置
6.3 升级的好处
- p50 提升灵活性
- p50 节约内存
6.4 降级
6.5 整数集合API
- p51 整数集合的操作API
第七章 压缩链表
- p52 压缩链表概念
7.1 压缩链表的构成
- p53 压缩链表组成部分详细说明
7.2 压缩链表节点的构成
- p54 previous_entry_length
- p55 压缩链表从表尾节点向表头结点进行遍历的完整过程
- p55 encoding
- p56 content
7.3 连锁更新
- p58 连锁更新
7.4 压缩链表API
- p59 压缩链表API
第八章 对象
8.1 对象的类型与编码
- p61 redisObject结构
- p61 类型
- p61 对象的类型
- p61 TYPE命令
- p62 编码和底层实现
- p62 encoding属性记录了对象所使用的编码
- p62 每种类型的对象可以使用的编码
- p63 OBJECT ENCODING命令
8.2 字符串对象
- p64 字符串对象的编码可以是int、raw或者embstr
- p65 embstr编码的字符串对象来保存短字符串值的好处
- p66 字符串对象保存各类型值得编码方式
- p66 编码的转换
- p67 字符串命令的实现
8.3 列表对象
- p68 列表对象的编码可以是ziplist或者Linkedlist
- p70 编码转换
- p70 列表对象使用ziplist编码的两个条件
8.4 哈希对象
- p71 哈希对象的编码可以是ziplist或者hashtable
- p73 编码转换
- p73 哈希对象使用ziplist编码的两个条件
- p74 哈希命令的实现
8.5 集合对象
- p75 集合对象的编码可以是intset或者hashtable
- p75 编码的转换
- p75 集合对象使用intset编码的两个条件
- p76 集合命令的实现
8.6 有序集合对象
- p77 有序集合对象的编码可以是ziplist或者skiplist
- p78 为什么有序集合需要同时使用跳跃表和字典来实现
- p79 编码的转换
- p79 有序集合对象使用ziplist编码的两个条件
- p80 有序集合命令的实现
8.7 类型检查与命令多态
- p82 类型检查的实现
- p83 类型检查过程
- p83 多态命令的实现
- p83 一些命令是多态的
8.8 内存回收
- p84 Redis使用引用计数法实现内存回收机制
- p84 引用计数规则
8.9 对象共享
- p85 让多个键共享同一个值对象需要执行两个步骤
- p86 Redis在初始化服务器时创建了一万个字符串对象,包含0到9999的所有整数值,并将它们作为共享对象
- p86 OBJECT REFCOUNT命令
- p87 为什么Redis不共享包含字符串的对象
8.10 对象的空转时长
- p87 OBJECT IDLETIME命令
第二部分 单机数据库的实现
第九章 数据库
9.1 服务器中的数据库
- p90 redisServer结构和redisDb结构
9.2 切换数据库
- p91 SELECT命令
- p92 SELECT命令实现原理
9.3 数据库键空间
- p93 键空间
- p94 添加新键
- p95 删除键
- p95 更新键
- p97 对键取值
- p98 其他键空间操作
- p98 读写键空间时的维护操作
- p98 服务器会记录键空间命中次数或键空间不命中次数
- p98 键的LRU时间
- p99 脏键标记
9.4 设置键的生存时间或过期时间
- p99 EXPIRE命令和PEXPIRE命令
- p99 EXPIREAT命令和PEXPIREAT命令
- p100 TTL命令和PTTL命令
- p100 设置过期时间
- p101 设置生存时间和设置过期时间的命令之间的转换
- p101 保存过期时间
- p101 过期字典
- p104 移除过期时间
- p104 PERSIST命令
- p105 计算并返回剩余生存时间
- p105 TTL命令和PTTL命令
- p106 过期键的判定
9.5 过期键删除策略
- p107 定时删除
- p108 惰性删除
- p108 定期删除
9.6 Redis的过期键删除策略
- p108 Redis服务器实际使用的是惰性删除和定期删除两种策略
- p109 惰性删除策略的实现
- p109 定期删除策略的实现
9.7 AOF、RDB和复制功能对过期键的处理
p111 生成RDB文件
- p111 已过期的键不会被保存到新创建的RDB文件中
p111 载入RDB文件
p112 AOF文件写入
p112 AOF重写
p112 复制
p113 数据库通知
9.8 数据库通知
- p113 数据库通知
- p114 键空间通知和键事件通知
- p114 notify-keyspace-events选项决定了服务器所发送通知的类型
- p115 发送通知
- p115 notifyKeyspaceEvent函数实现了发送数据库通知的功能
- p116 发送通知的实现
第十章 RDB持久化
- p118 数据库状态
10.1 RDB文件的创建与载入
- p119 SAVE命令和BGSAVE命令
- p120 AOF文件的更新频率通常比RDB文件的更新频率高
- p120 SAVE命令执行时的服务器状态
- p120 SAVE命令执行时,Redis服务器将被阻塞
- p120 BGSAVE命令执行时候的服务器状态
- p121 BGSAVE命令执行期间,服务器处理SAVE、BGSAVE、BGREWRITEAOF三个命令的方式会发生变化
- p121 RDB文件载入时的服务器状态
- p121服务器在载入RDB文件期间,会一直处于阻塞状态,直到载入工作完成
10.2 自动间隔性保存
- p121 save选项
- p122 设置保存条件
- p122 save选项默认条件
- p123 dirty计数器和lastsave属性
- p124 设置保存条件是否满足
- p124 服务器周期性操作函数serverCron
10.3 RDB文件结构
p125 RDB文件结构
p126 check_sum校验和
p126 databases部分
- p126 RDB文件中的数据库结构
p127 key_value_pairs部分
- p127 不带过期时间的键值对结构
- p128 带有过期时间的键值对结构
p128 value的编码
10.4 分析RDB文件
- p133 od命令可以分析RDB文件
- p133 不包含任何键值对的RDB文件
- p134 包含字符串键的RDB文件
- p135 包含带有过期时间的字符串键的RDB文件
- p135 包含一个集合键的RDB文件
- p136 关于分析RDB文件的说明
第十一章 AOF持久化
11.1 AOF持久化的实现
- p139 命令追加
- p140 AOF文件的写入与同步
- p140 Redis的服务器进程是一个事件循环
- p140 appendfsync选项
- p141 文件的写入和同步
11.2 AOF的载入与数据还原
- p142 Redis读取AOF文件并还原数据库的详细步骤
11.3 AOF重写
- p143 AOF重写
- p143 AOF文件重写的实现
- p144 AOF重写功能的实现原理
- p147 元素数量超过一个参数时,重写程序使用多条命令来记录键的值
- p147 AOF后台重写
- p148 AOF重写缓冲区
第十二章 事件
- p151 文件事件和时间事件
12.1 文件事件
- p151 文件事件处理器
- p152 文件事件处理器的构成
- p152 I/O多路复用程序的实现
- p152 Redis的I/O多路复用程序的所有功能都是通过包装常见的I/O多路复用函数库来实现的
- p153 事件的类型
- p153 READABLE事件和WRITABLE事件
- p153 API
- p154 文件时间的处理器
- p154 连接应答处理器
- p155 命令请求处理器
- p155 命令回复处理器
- p155 一次完整的客户端与服务器连接事件示例
12.2 时间事件
- p156 定时事件和周期性事件
- p157 时间事件的实现
- p157 API
- p159 时间事件应用实例:serverCron函数
12.3 事件的调度与执行
- p160 事件处理角度下的服务器运行流程
第十三章 客户端
- p162 redisClient结构-客户端状态
- p163 clients链表
13.1 客户端属性
- p163 套接字描述符
- p164 名字
- p165 标志
- p166 PUBSUB命令和SCRIPT LOAD命令的特殊性
- p167 输入缓冲区
- p168 命令与命令参数
- p169 命令的实现函数
- p169 命令表
- p169 输出缓冲区
- p171 身份验证
- p171 时间
- p172 客户端空转时间
13.2 客户端的创建与关闭
- p172 创建普通客户端
- p173 关闭普通客户端
- p173 普通客户端关闭的原因
- p173 两种限制客户端输出缓冲区大小的方式
- p174 Lua脚本的伪客户端
- p174 AOF文件的伪客户端
第十四章
14.1 命令请求的执行过程
- p177 发送命令请求
- p177 读取命令请求
- p178 命令执行器(1):查找命令实现
- p178 redisCommand结构的主要属性
- p179 slags属性的标识
- p181 命令名字的大小写不影响命令表的查找结果
- p181 命令执行器(2):执行预备操作
- p182 命令执行器(3):调用命令的实现函数
- p183 命令执行器(4):执行后续工作
- p184 将命令回复发送给客户端
- p184 客户端接收并打印命令回复
14.2 serverCron函数
- p184 更新服务器时间缓存
- p185 更新LRU时钟
- p186 更新服务器每秒执行命令次数
- p187 更新服务器内存峰值记录
- p188 处理SIGTERM信号
- p189 管理客户端资源
- p189 管理数据库资源
- p189 执行被延迟的BGREWRITEAOF
- p190 检查持久化操作的运行状态
- p191 将AOF缓冲区中的内容写入AOF
- p191 关闭异步客户端
- p191 增加cronloops计数器的值
14.3 初始化服务器
- p192 初始化服务器状态结构
- p193 initServerConfig函数
- p193 载入配置选项
- p194 初始化服务器数据结构
- p194 initServer函数
- p195 共享对象
- p195 还原数据库状态
- p196 执行事件循环
第三部分 多机数据库的实现
第十五章 复制
15.1 旧版复制功能的实现
- p199 SYNC命令执行步骤
- p200 命令传播
15.2 旧版复制功能的缺陷
- p201 初次复制和断线后重复制
- p203 SYNC命令是一个非常耗费资源的操作
15.3 新版复制功能的实现
- p203 完整重同步和部分重同步
15.4 部分重同步的实现
p205 复制偏移量
p206 复制积压缓冲区
- p206 固定长度先进先出队列
- p209 根据需要调整复制积压缓冲区大小
p208 服务器运行ID
15.5 PSYNC命令的实现
- p209 PSYNC命令的两种调用方法
- p209 接收到PSYNC命令的主服务器向从服务器返回的三种回复
15.6 复制的实现
- p211 步骤1:设置主服务器的地址和端口
- p212 步骤2:建立套接字连接
- p212 步骤3:发送PING命令
- p213 步骤4:身份验证
- p214 步骤5:发送端口信息
- p215 步骤6:同步
- p216 步骤7:命令传播
15.7 心跳检测
- p216 发送REPLCONF ACK命令对于主从服务器有三个作用
- p216 检测主从服务器的网络连接状态
- p217 辅助实现min-slaves配置选项
- p127 检测命令丢失
- p218 Redis2.8版本以前的命令丢失
第十六章 Sentinel
- p219 Sentinel
- p220 故障转移操作
16.1 启动并初始化Sentinel
- p220 启动一个Sentinel可以使用命令redis-sentinel
- p221 当一个Sentinel启动时,它需要以下步骤
- p221 初始化服务器
- p221 Sentinel模式下Redis服务器主要功能的使用情况
- p222 使用Sentinel专用代码
- p222 初始化Sentinel状态
- p223 初始化Sentinel状态的master属性
- p223 每个sentinelRedisInstence结构代表一个被监视的Redis服务器实例
- p226 创建连向主服务器的网络连接
- p226 Sentinel会创建两个连向主服务器的异步网络连接
16.2 获取主服务器信息
- p227 主服务器INFO命令回复
16.3 获取从服务器信息
- p229 从服务器INFO命令回复
16.4 向主服务器和从服务器发送信息
- p230 信息中和Sentinel有关的参数
- p231 信息中和主服务器有关的参数
16.5 接收来自主服务器和从服务器的频道信息
- p232 更新sentinels字典
- p234 创建连向其他Sentinel的命令连接
- p234 Sentinel之间不会创建订阅连接
16.6 检测主观下线状态
- p235 down-after-milliseconds选项
- p235 主观下线时长选项的作用范围
- p236 多个Sentinel设置的主观下线时长可能不同
16.7 检查客观下线状态
- p236 发送SENTINEL is-master-down-by-addr命令
- p237 接收SENTINEL is-master-down-by-addr命令
- p237 接收SENTINEL is-master-down-by-addr命令的回复
- p238 客观下线状态的判断条件
16.8 选举领头Sentinel
- 当一个主服务器被判断为客观下线时进行选举
16.9 故障转移
- p240 故障转移的三个步骤
- p241 选出新的主服务器
- p241 新的主服务器是怎样挑选出来的
- p242 修改从服务器的复制目标
- p243 将旧的主服务器变为从服务器
第十七章 集群
17.1 节点
- p245 CLUSTER MEET命令
- p247 启动节点
- p247 集群数据结构
- p247 clusterNode结构
- p248 clusterLink结构
- p249 clusterState结构
- p250 CLUSLTER MEET命令的实现
17.2 槽指派
- p253 记录节点的槽指派信息
- p254 传播节点的槽指派信息
- p255 记录集群所有槽的指派信息
- p257 CLUSTER ADDSLOTS命令的实现
17.3 在集群中的执行命令
- p260 计算键属于哪个槽
- p260 判断槽是否由当前节点负责处理
- p261 MOVED错误
- p261 节点数据库的实现
- p261 slots_to_key跳跃表
17.4 重新分片
- p266 重新分片的实现原理
17.5 ASK错误
- p268 CLUSTER SETSLOT IMPORTING命令的实现
- p269 CLUSTER SETSLOT MIGRATING命令的实现
- p270 ASK错误
- p271 ASKING命令
- p273 ASK错误和MOVED错误的区别
17.6 复制与故障转移
- p275 设置从节点
- p278 故障检测
- p280 故障转移
- p280 选举新的主节点
17.7 消息
- p282 消息头
- p284 MEET、PING、PONG消息的实现
- p284 Gossip协议
- p285 FAIL消息的实现
- p286 PUBLISH消息的实现
第四部分 独立功能的实现
第十八章 发布与订阅
- p290 SUBSCRIBE命令
- p290 PSUBSCRIBE命令
18.1 频道的订阅与退订
- p292 pubsub_channels字典
- p293 订阅频道
- p294 退订频道
18.2 模式的订阅与退订
- p296 订阅模式
- p297 退订模式
18.3 发送消息
- p298 将消息发送给频道订阅者
- p299 将消息发送给模式订阅者
18.4 查看订阅信息
- p301 PUBSUB CHANNELS
- p301 PUBSUB NUMSUB
- p303 PUBSUB NUMPAT
第十九章 事务
19.1 事务的实现
- p306 事务开始
- p306 MULTI命令
- p306 命令入队
- p307 事务队列
- p307 mstate属性
- p309 执行事务
- p309 EXEC命令
19.2 WATCH命令的实现
- p311 使用WATCH命令监视数据库键
- p312 监视机制的触发
- p313 判断事务是否安全
- p313 一个完整的WATCH事务执行过程
19.3 事务的ACID性质
- p314 原子性
- p315 一致性
- p316 入队错误
- p317 执行错误
- p317 服务器停机
- p318 隔离性
- p318 耐久性
- p319 no-appendfsync-on-rewrite配置选项对耐久性的影响
第二十章 Lua脚本
第二十一章 排序
- p344 ALPHA选项
21.1 SORT<key>命令的实现
- p346 服务器执行SORT numbers命令的详细步骤
21.2 ALPHA选项的实现
- p348 服务器执行SORT fruits ALPHA命令的详细步骤
21.3 ASC选项和DESC选项的实现
21.4 BY选项的实现
- p350 服务器执行
SORT fruits BY \*-price
命令的详细步骤
21.5 带有ALPHA选项的BY选项的实现
- p352 服务器执行
SORT fruits BY \*-id ALPHA
命令的详细步骤
21.6 LIMIT选项的实现
- p354 服务器执行
SORT alphabet ALPHA LIMIT 0 4
命令的详细步骤
21.7 GET选项的实现
- p356 服务器执行
SORT studenst ALPHA GET \*-name
命令的详细步骤
21.8 STORE选项的实现
- p359 服务器执行
SORT students ALPHA GET \*-name
命令的详细步骤
21.9 多个选项的执行顺序
- p359 选项的的执行顺序
- p259 一个SORT命令的执行过程可以分为以下四步
第二十二章 二进制位数组
- p362 Redis提供了SETBIT、GETBIT、BITCOUNT、BITOP四个命令用于处理二进制位数组
22.1 位数组的表示
- p363 Redis使用字符串对象来表示位数组
22.2 GETBIT命令的实现
22.3 SETBIT命令的实现
- p367 SETBIT命令的执行示例
- p367 带扩展操作的SETBIT命令示例
22.4 BITCOUNT命令的实现
- p370 二进制位统计算法(1):遍历算法
- p370 二进制位统计算法(2):查表算法
- p371 二进制位统计算法(3):variable-precision SWAR算法
- p372 计算汉明重量
- p374 二进制位统计算法(4):Redis的实现
22.5 BITOP命令的实现
第二十三章 慢查询日志
- p379 SLOWLOG GET命令
23.1 慢查询记录的保存
23.2 慢查询日志的阅览和删除
23.3 添加新日志
第二十四章 监视器
24.1 成为监视器
24.2 向监视器发送命令信息
《Redis设计与实现》知识点目录的更多相关文章
- Redis | 第一部分:数据结构与对象 上篇《Redis设计与实现》
目录 前言 1. 简单动态字符串 1.1 SDS的定义 1.2 空间预分配与惰性空间释放 1.3 SDS的API 2. 链表 2.1 链表与节点的定义 2.2 链表的API 3. 字典 3.1 哈希表 ...
- Redis | 第一部分:数据结构与对象 下篇《Redis设计与实现》
目录 前言 1. Redis对象概述 1.1 对象的定义 2. 字符串对象 3. 列表对象 3.1 quicklist 快速链表 4. 哈希对象 5. 集合对象 6. 有序集合对象 7. Redis对 ...
- Redis | 第一部分:数据结构与对象 中篇《Redis设计与实现》
目录 前言 1. 跳跃表 1.1 跳跃表与其节点的定义 1.2 跳跃表的API 2. 整数集合 2.1 整数集合的实现 2.2 整数集合的类型升级 2.3 整数集合的API 3. 压缩列表 3.1 压 ...
- web开发前端面试知识点目录整理
web开发前端面试知识点目录整理 基本功考察 关于Html 1. html语义化标签的理解; 结构化的理解; 能否写出简洁的html结构; SEO优化 2. h5中新增的属性; 如自定义属性data, ...
- 如何使用redis设计关系数据库
目录 redis设计关系数据库 前言 设计用户信息表结构 hash存储记录 set存储id 图示 索引/查询: 1.select 查询所有记录 : 类似sql的select from table_na ...
- 《Redis设计与实现》
<Redis设计与实现> 基本信息 作者: 黄健宏 丛书名: 数据库技术丛书 出版社:机械工业出版社 ISBN:9787111464747 上架时间:2014-6-3 出版日期:2014 ...
- redis的几个知识点
Redis的全称是Remote Dictionary Server,即远程字典服务,通常用作服务器缓存服务. 这里通过Redis的几个知识点来了解Redis. Redis的通讯协议 Redis的通讯协 ...
- 探索Redis设计与实现10:Redis的事件驱动模型与命令执行过程
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- Redis | 第4章 Redis中的数据库《Redis设计与实现》
目录 前言 1. Redis中的数据库 2. 数据库的键空间 3. 键的生成时间与过期时间 4. Redis中的过期键删除策略 5. AOF.RDB和复制功能对过期键的处理 5.1 生成 RDB 文件 ...
随机推荐
- 2021.9.14考试总结[NOIP模拟53]
T1 ZYB和售货机 容易发现把每个物品都买成$1$是没有影响的. 然后考虑最后一个物品的方案,如果从$f_i$向$i$连边,发现每个点有一个出度多个入度,可以先默认每个物品都能买且最大获利,这样可以 ...
- C++的指针使用心得
使用C++有一段时间了,C++的手动内存管理缺失很麻烦,一不小心容易产生内存泄漏.自己总结了一点使用原则(不一定对),备注一下,避免忘记. 1.类外部传来的指针不处理 2.Qt对象管理的内存不处理 3 ...
- 鸿蒙轻内核M核的故障管家:Fault异常处理
摘要:本文先简单介绍下Fault异常类型,向量表及其代码,异常处理C语言程序,然后详细分析下异常处理汇编函数实现代码. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列十八 Fault异常处理& ...
- 你知道怎么从jar包里获取一个文件的内容吗
目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...
- linux shell exec 关联文件描述符
在写shell脚本时,如果多个命令的输入或输出都是同一个文件,而这个文件的路径和名字都很长,则需要书写很多次同样的路径会很浪费时间,我们可以使用exec命令来关联一个自定义的文件描述符到一个特定的文件 ...
- 把字符串转换成整数 牛客网 剑指Offer
把字符串转换成整数 牛客网 剑指Offer 题目描述 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串 ...
- Spark记录(一):Spark全景概述
一.Spark是什么 Spark是一个开源的大数据处理引擎. 二.Spark的主要组件如下图所示: 三.Spark运行时架构 Spark共有三种运行模式:本地模式.集群模式.客户端模式. 生产环境基 ...
- Qt5 C++ GUI界面 开发环境配置 详细教程
本博客已暂停更新,需要请转新博客http://www.whbwiki.com/333.html Qt 下载 Qt 体积很大,有 1GB~3GB,官方下载通道非常慢,相信很多读者会崩溃,所以建议大家使用 ...
- 【数据结构&算法】09-队列概念&参考源码
目录 前言 队列的定义 队列的抽象数据类型 循环队列与链式队列对比 循环队列 特点 定义 循环队列相关计算 链式队列 定义 阻塞队列 并发队列 代码实现 循环队列代码 链式队列实现 前言 李柱明博客: ...
- PTA 7-2 邻接表创建无向图 (20分)
PTA 7-2 邻接表创建无向图 (20分) 采用邻接表创建无向图G ,依次输出各顶点的度. 输入格式: 输入第一行中给出2个整数i(0<i≤10),j(j≥0),分别为图G的顶点数和边数. 输 ...