本篇文章我们用go来实现红黑树,部分参考资料如下:

1.节点定义

type RBNode struct {
color uint8
key Type
left, right, parent *RBNode
} type RBRoot struct {
node *RBNode
}

2.树的遍历

// 前序遍历
func PreTraverse(p *RBNode) {
if p != nil {
fmt.Printf("%d ", p.key)
PreTraverse(p.left)
PreTraverse(p.right)
}
} // 中序遍历
func InTraverse(p *RBNode) {
if p != nil {
InTraverse(p.left)
fmt.Printf("%d ", p.key)
InTraverse(p.right)
}
} // 前序遍历
func PostTraverse(p *RBNode) {
if p != nil {
PostTraverse(p.left)
PostTraverse(p.right)
fmt.Printf("%d ", p.key)
}
}

3.树的旋转

/*
* 对红黑树的节点(x)进行左旋转
情况1:
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
情况2:
* px px
* / /
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
情况3:
* px px
* \ \
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
*
*/
func left_rotate(root *RBRoot, x *RBNode) {
var y *RBNode = x.right // ly 和 x 的关系
x.right = y.left
if y.left != nil {
y.left.parent = x
} // px 和 y 的关系(要考虑px为空,即x为根节点的情况)
y.parent = x.parent
if x.parent == nil {
root.node = y
} else {
if x.parent.left == x {
x.parent.left = y
} else {
x.parent.right = y
}
} // y 和 x 的关系
y.left = x
x.parent = y } /*
* 对红黑树的节点(y)进行右旋转
* 情况1:
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
* 情况2:
* py py
* / /
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
* 情况3:
* py py
* \ \
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
*/
func right_rotate(root *RBRoot, y *RBNode) {
var x *RBNode = y.left // rx 和 y 的关系
y.left = x.right
if x.right != nil {
x.right.parent = y
} // py 和 x 的关系(要考虑py为空,即y为根节点的情况)
x.parent = y.parent
if y.parent == nil {
root.node = x
} else {
if y.parent.right == y {
y.parent.right = x
} else {
y.parent.left = x
}
} // y 和 x 的关系
x.right = y
y.parent = x
}

4.添加节点

// 添加节点:将节点(node)插入到红黑树中
func Add(root *RBRoot, node *RBNode) {
var y *RBNode
var x *RBNode = root.node // 找到node应插入位置的父节点
for x != nil {
y = x
if node.key < x.key {
x = x.left
} else {
x = x.right
}
}
// 设置node和父节点的关系
node.parent = y
if y != nil {
if node.key < y.key {
y.left = node
} else {
y.right = node
}
} else {
root.node = node
}
// 设置节点为红色
node.color = RED
// 修正为红黑树
add_fixup(root, node) } // 红黑树插入修正
func add_fixup(root *RBRoot, node *RBNode) {
var parent, gparent *RBNode // 若“父节点存在,并且父节点的颜色是红色”
for parent=node.parent; parent != nil && rb_is_red(parent); {
gparent = parent.parent //若“父节点”是“祖父节点的左孩子”
if parent == gparent.left {
var uncle *RBNode = gparent.right
// Case 1条件:叔叔节点是红色
if uncle != nil && rb_is_red(uncle) {
rb_set_black(uncle)
rb_set_black(parent)
rb_set_red(gparent)
node = gparent
continue
}
// Case 2条件:叔叔是黑色,且当前节点是右孩子
if parent.right == node {
left_rotate(root, parent)
var tmp *RBNode = parent
parent = node
node = tmp
}
// Case 3条件:叔叔是黑色,且当前节点是左孩子。
rb_set_black(parent)
rb_set_red(gparent)
right_rotate(root, gparent)
} else {
//若“父节点”是“祖父节点的右孩子” var uncle *RBNode = gparent.left
// Case 1条件:叔叔节点是红色
if uncle != nil && rb_is_red(uncle) {
rb_set_black(uncle)
rb_set_black(parent)
rb_set_red(gparent)
node = gparent
continue
}
// Case 2条件:叔叔是黑色,且当前节点是左孩子
if parent.left == node {
right_rotate(root, parent)
var tmp *RBNode = parent
parent = node
node = tmp
}
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
rb_set_black(parent)
rb_set_red(gparent)
left_rotate(root, gparent)
}
}
// 将根节点设为黑色
rb_set_black(root.node)
}

5.删除节点

func Delete(root *RBRoot, node *RBNode) {
var child, parent *RBNode
var color uint8 // 被删除节点的"左右孩子都不为空"的情况。
if node.left != nil && node.right != nil {
// 获取后继节点
var replace *RBNode = node.right
for replace.left != nil {
replace = replace.left
} // "node节点"不是根节点
if node.parent != nil {
if node.parent.left == node {
node.parent.left = replace
} else {
node.parent.right = replace
}
} else {
// "node节点"是根节点,更新根节点。
root.node = replace
}
// child是"取代节点"的右孩子,也是需要"调整的节点"。
// "取代节点"肯定不存在左孩子!因为它是一个后继节点。
child = replace.right
parent = replace.parent
// 保存"取代节点"的颜色(注意这里删掉的是node节点,但实际删掉的颜色是replace的)
color = replace.color // "被删除节点"是"它的后继节点的父节点"
if parent == node {
parent = replace
} else {
// child不为空
if child != nil {
child.parent = parent
}
parent.left = child replace.right = node.right
node.right.parent = replace
} replace.parent = node.parent
replace.color = node.color
replace.left = node.left
node.left.parent = replace if color == BLACK {
delete_fixup(root, child, parent)
} return
} if node.left != nil {
child = node.left
} else {
child = node.right
} parent = node.parent
color = node.color // 保存"取代节点"的颜色 if child != nil {
child.parent = parent
} // "node节点"不是根节点
if parent != nil {
if parent.left == node {
parent.left = child
} else {
parent.right = child
}
} else {
root.node = child
} if color == BLACK {
delete_fixup(root, child, parent)
} } func delete_fixup(root *RBRoot, node *RBNode, parent *RBNode) {
var other *RBNode for (node == nil || rb_is_black(node)) && node != root.node {
// node是父节点的左孩子
if parent.left == node {
other = parent.right
// Case 1: node的兄弟节点是红色的
if rb_is_red(other) {
rb_set_black(other)
rb_set_red(parent)
left_rotate(root, parent)
other = parent.right
}
// Case 2: node的兄弟w是黑色,且w的俩个孩子也都是黑色的
if (other.left == nil || rb_is_black(other.left)) && (other.right == nil || rb_is_black(other.right)) {
rb_set_red(other)
node = parent
parent = node.parent
} else {
// Case 3: node的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
if other.right == nil || rb_is_black(other.right) {
rb_set_black(other.left)
rb_set_red(other)
right_rotate(root, other)
other = parent.right
}
// Case 4: node的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
other.color = parent.color
rb_set_black(parent)
rb_set_black(other.right)
left_rotate(root, parent)
node = root.node
break
}
} else {
other = parent.left
// Case 1: node的兄弟w是红色的
if rb_is_red(other) {
rb_set_black(other)
rb_set_red(parent)
right_rotate(root, parent)
other = parent.left
}
// Case 2: node的兄弟w是黑色,且w的俩个孩子也都是黑色的
if (other.left == nil || rb_is_black(other.left)) && (other.right == nil || rb_is_black(other.right)) {
rb_set_red(other)
node = parent
parent = node.parent
} else {
// Case 3: node的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
if other.left == nil || rb_is_black(other.left) {
rb_set_black(other.right)
rb_set_red(other)
left_rotate(root, other)
other = parent.left
}
// Case 4: node的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
other.color = parent.color
rb_set_black(parent)
rb_set_black(other.left)
right_rotate(root, parent)
node = root.node
break
}
}
} if node != nil {
rb_set_black(node)
}
}

6.完整代码

package main

import "fmt"

const RED  = 0
const BLACK = 1 type Type int type RBNode struct {
color uint8
key Type
left, right, parent *RBNode
} type RBRoot struct {
node *RBNode
} func rb_is_red(node *RBNode) bool {
return node.color == RED
} func rb_is_black(node *RBNode) bool {
return node.color == BLACK
} func rb_set_red(node *RBNode) {
node.color = RED
} func rb_set_black(node *RBNode) {
node.color = BLACK
} // 前序遍历
func PreTraverse(p *RBNode) {
if p != nil {
fmt.Printf("%d ", p.key)
PreTraverse(p.left)
PreTraverse(p.right)
}
} // 中序遍历
func InTraverse(p *RBNode) {
if p != nil {
InTraverse(p.left)
fmt.Printf("%d ", p.key)
InTraverse(p.right)
}
} // 前序遍历
func PostTraverse(p *RBNode) {
if p != nil {
PostTraverse(p.left)
PostTraverse(p.right)
fmt.Printf("%d ", p.key)
}
} // 查找键值为key的节点
func Find(node *RBNode, key Type) *RBNode {
for node != nil && node.key != key {
if key < node.key {
node = node.left
} else {
node = node.right
}
}
return node
} // 打印红黑树
func Print(node *RBNode, key Type, direction int) {
if node != nil {
if direction == 0 {
fmt.Printf("%2d(B) is root\n", node.key)
} else {
var color, _direction string
if rb_is_red(node) {
color = "R"
} else {
color = "B"
}
if direction == 1 {
_direction = "right"
} else {
_direction = "left"
}
// TODO: 这里key 和 %d 的关系
fmt.Printf("%2d(%s) is %2d's %6s child\n", node.key, color, key, _direction)
}
Print(node.left, node.key, -1)
Print(node.right, node.key, 1)
}
} // 打印根节点的所有路径(检测两条红黑树特性)
func PrintRoute(node *RBNode) {
if node == nil {
return
}
if node.left == nil && node.right == nil {
var tmp *RBNode = node
var num int
for tmp != nil {
var color string
if rb_is_red(tmp) {
color = "R"
} else {
color = "B"
num++
}
fmt.Printf("%2d(%s)-->", tmp.key, color)
if tmp.parent != nil && (tmp.color == RED && tmp.parent.color == RED) {
fmt.Println("检测到违反红黑树特性:红节点的子节点是红节点")
}
tmp = tmp.parent
}
fmt.Printf("共 %d 个黑节点\n", num)
}
PrintRoute(node.left)
PrintRoute(node.right)
} /*
* 对红黑树的节点(x)进行左旋转
情况1:
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
情况2:
* px px
* / /
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
情况3:
* px px
* \ \
* x y
* / \ --(左旋)--> / \
* lx y x ry
* / \ / \
* ly ry lx ly
*
*/
func left_rotate(root *RBRoot, x *RBNode) {
var y *RBNode = x.right // ly 和 x 的关系
x.right = y.left
if y.left != nil {
y.left.parent = x
} // px 和 y 的关系(要考虑px为空,即x为根节点的情况)
y.parent = x.parent
if x.parent == nil {
root.node = y
} else {
if x.parent.left == x {
x.parent.left = y
} else {
x.parent.right = y
}
} // y 和 x 的关系
y.left = x
x.parent = y } /*
* 对红黑树的节点(y)进行右旋转
* 情况1:
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
* 情况2:
* py py
* / /
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
* 情况3:
* py py
* \ \
* y x
* / \ --(右旋)--> / \
* x ry lx y
* / \ / \
* lx rx rx ry
*/
func right_rotate(root *RBRoot, y *RBNode) {
var x *RBNode = y.left // rx 和 y 的关系
y.left = x.right
if x.right != nil {
x.right.parent = y
} // py 和 x 的关系(要考虑py为空,即y为根节点的情况)
x.parent = y.parent
if y.parent == nil {
root.node = x
} else {
if y.parent.right == y {
y.parent.right = x
} else {
y.parent.left = x
}
} // y 和 x 的关系
x.right = y
y.parent = x
} // 添加节点:将节点(node)插入到红黑树中
func Add(root *RBRoot, node *RBNode) {
var y *RBNode
var x *RBNode = root.node // 找到node应插入位置的父节点
for x != nil {
y = x
if node.key < x.key {
x = x.left
} else {
x = x.right
}
}
// 设置node和父节点的关系
node.parent = y
if y != nil {
if node.key < y.key {
y.left = node
} else {
y.right = node
}
} else {
root.node = node
}
// 设置节点为红色
node.color = RED
// 修正为红黑树
add_fixup(root, node) } // 红黑树插入修正
func add_fixup(root *RBRoot, node *RBNode) {
var parent, gparent *RBNode // 若“父节点存在,并且父节点的颜色是红色”
for parent=node.parent; parent != nil && rb_is_red(parent); {
gparent = parent.parent //若“父节点”是“祖父节点的左孩子”
if parent == gparent.left {
var uncle *RBNode = gparent.right
// Case 1条件:叔叔节点是红色
if uncle != nil && rb_is_red(uncle) {
rb_set_black(uncle)
rb_set_black(parent)
rb_set_red(gparent)
node = gparent
continue
}
// Case 2条件:叔叔是黑色,且当前节点是右孩子
if parent.right == node {
left_rotate(root, parent)
var tmp *RBNode = parent
parent = node
node = tmp
}
// Case 3条件:叔叔是黑色,且当前节点是左孩子。
rb_set_black(parent)
rb_set_red(gparent)
right_rotate(root, gparent)
} else {
//若“父节点”是“祖父节点的右孩子” var uncle *RBNode = gparent.left
// Case 1条件:叔叔节点是红色
if uncle != nil && rb_is_red(uncle) {
rb_set_black(uncle)
rb_set_black(parent)
rb_set_red(gparent)
node = gparent
continue
}
// Case 2条件:叔叔是黑色,且当前节点是左孩子
if parent.left == node {
right_rotate(root, parent)
var tmp *RBNode = parent
parent = node
node = tmp
}
// Case 3条件:叔叔是黑色,且当前节点是右孩子。
rb_set_black(parent)
rb_set_red(gparent)
left_rotate(root, gparent)
}
}
// 将根节点设为黑色
rb_set_black(root.node)
} func Delete(root *RBRoot, node *RBNode) {
var child, parent *RBNode
var color uint8 // 被删除节点的"左右孩子都不为空"的情况。
if node.left != nil && node.right != nil {
// 获取后继节点
var replace *RBNode = node.right
for replace.left != nil {
replace = replace.left
} // "node节点"不是根节点
if node.parent != nil {
if node.parent.left == node {
node.parent.left = replace
} else {
node.parent.right = replace
}
} else {
// "node节点"是根节点,更新根节点。
root.node = replace
}
// child是"取代节点"的右孩子,也是需要"调整的节点"。
// "取代节点"肯定不存在左孩子!因为它是一个后继节点。
child = replace.right
parent = replace.parent
// 保存"取代节点"的颜色(注意这里删掉的是node节点,但实际删掉的颜色是replace的)
color = replace.color // "被删除节点"是"它的后继节点的父节点"
if parent == node {
parent = replace
} else {
// child不为空
if child != nil {
child.parent = parent
}
parent.left = child replace.right = node.right
node.right.parent = replace
} replace.parent = node.parent
replace.color = node.color
replace.left = node.left
node.left.parent = replace if color == BLACK {
delete_fixup(root, child, parent)
} return
} if node.left != nil {
child = node.left
} else {
child = node.right
} parent = node.parent
color = node.color // 保存"取代节点"的颜色 if child != nil {
child.parent = parent
} // "node节点"不是根节点
if parent != nil {
if parent.left == node {
parent.left = child
} else {
parent.right = child
}
} else {
root.node = child
} if color == BLACK {
delete_fixup(root, child, parent)
} } func delete_fixup(root *RBRoot, node *RBNode, parent *RBNode) {
var other *RBNode for (node == nil || rb_is_black(node)) && node != root.node {
// node是父节点的左孩子
if parent.left == node {
other = parent.right
// Case 1: node的兄弟节点是红色的
if rb_is_red(other) {
rb_set_black(other)
rb_set_red(parent)
left_rotate(root, parent)
other = parent.right
}
// Case 2: node的兄弟w是黑色,且w的俩个孩子也都是黑色的
if (other.left == nil || rb_is_black(other.left)) && (other.right == nil || rb_is_black(other.right)) {
rb_set_red(other)
node = parent
parent = node.parent
} else {
// Case 3: node的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
if other.right == nil || rb_is_black(other.right) {
rb_set_black(other.left)
rb_set_red(other)
right_rotate(root, other)
other = parent.right
}
// Case 4: node的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
other.color = parent.color
rb_set_black(parent)
rb_set_black(other.right)
left_rotate(root, parent)
node = root.node
break
}
} else {
other = parent.left
// Case 1: node的兄弟w是红色的
if rb_is_red(other) {
rb_set_black(other)
rb_set_red(parent)
right_rotate(root, parent)
other = parent.left
}
// Case 2: node的兄弟w是黑色,且w的俩个孩子也都是黑色的
if (other.left == nil || rb_is_black(other.left)) && (other.right == nil || rb_is_black(other.right)) {
rb_set_red(other)
node = parent
parent = node.parent
} else {
// Case 3: node的兄弟w是黑色的,并且w的左孩子是红色,右孩子为黑色。
if other.left == nil || rb_is_black(other.left) {
rb_set_black(other.right)
rb_set_red(other)
left_rotate(root, other)
other = parent.left
}
// Case 4: node的兄弟w是黑色的;并且w的右孩子是红色的,左孩子任意颜色。
other.color = parent.color
rb_set_black(parent)
rb_set_black(other.left)
right_rotate(root, parent)
node = root.node
break
}
}
} if node != nil {
rb_set_black(node)
}
} func main() {
//var datas = []Type{10, 40, 30, 60, 90, 70, 20, 50, 80}
var datas = []Type{10, 40, 30, 60, 90, 70, 20, 80} var root *RBRoot = new(RBRoot)
for _, data := range datas {
var node = &RBNode{key:data}
Add(root, node)
}
fmt.Print("前序遍历:")
PreTraverse(root.node)
fmt.Print("\n中序遍历:")
InTraverse(root.node)
fmt.Print("\n后序遍历:")
PostTraverse(root.node)
fmt.Print("\n\n") Print(root.node, root.node.key, 0)
fmt.Print("\n") var delNode = Find(root.node, 30)
Delete(root, delNode)
Print(root.node, root.node.key, 0)
fmt.Print("\n")
PrintRoute(root.node) }

(四)用go实现红黑树的更多相关文章

  1. Linux红黑树(二)——访问节点

    核心对红黑树使用两点说明 1.头文件 <Documentation/rbtree.txt> Linux's rbtree implementation lives in the file ...

  2. 红黑树(四)之 C++的实现

    概要 前面分别介绍红黑树的理论知识和红黑树的C语言实现.本章是红黑树的C++实现,若读者对红黑树的理论知识不熟悉,建立先学习红黑树的理论知识,再来学习本章. 目录1. 红黑树的介绍2. 红黑树的C++ ...

  3. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t

    新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  4. 数据结构(四)--- 红黑树(RedBlock-Tree)

      文章图片来自邓俊辉老师课件 先提几个问题去思考学习本文 : 红黑树和2-4树(B-Tree)很像,那么它存在的动机又是什么呢 插入和删除操作的逻辑又是怎么样的,时间和空间复杂度可以达到怎么样 和 ...

  5. 菜鸟nginx源码剖析数据结构篇(四)红黑树ngx_rbtree_t[转]

    菜鸟nginx源码剖析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn ...

  6. 第十四章 红黑树——C++代码实现

    红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的二叉查找树.红黑树是特殊的二叉查找树,意味着它满足二叉查找树的特征:任意一个节点所包含的键值,大于等于左孩子的键 ...

  7. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  8. 算法设计和数据结构学习_5(BST&AVL&红黑树简单介绍)

    前言: 节主要是给出BST,AVL和红黑树的C++代码,方便自己以后的查阅,其代码依旧是data structures and algorithm analysis in c++ (second ed ...

  9. 数据结构中很常见的各种树(BST二叉搜索树、AVL平衡二叉树、RBT红黑树、B-树、B+树、B*树)

    数据结构中常见的树(BST二叉搜索树.AVL平衡二叉树.RBT红黑树.B-树.B+树.B*树) 二叉排序树.平衡树.红黑树 红黑树----第四篇:一步一图一代码,一定要让你真正彻底明白红黑树 --- ...

  10. 红黑树(二)之 C语言的实现

    概要 红黑树在日常的使用中比较常用,例如Java的TreeMap和TreeSet,C++的STL,以及Linux内核中都有用到.之前写过一篇文章专门介绍红黑树的理论知识,本文将给出红黑数的C语言的实现 ...

随机推荐

  1. 【LeetCode字符串#05】基于个人理解的KMP算法图解,以及应用到strStr()函数实现

    KMP算法(用于实现 strStr()) strStr()函数是用来在一个字符串中搜索是否存在另一个字符串的函数,其匹配字符串方式为KMP算法 KMP算法基础理论 假设有如下两个字符串 文本串 aab ...

  2. pandas连接msyql报(1115, "Unknown character set: 'utf8mb4'")错误

    代码如下: 报错如下: 首先,为什么会出现这个错误: 分析如下: 随着智能手机的普及,我们开始经常使用表情符号.��更好的帮助我们进行交流.但是mysql的utf8编码只支持3字节的数据,而移动端的表 ...

  3. JumpServer(v2.28.6) 堡垒机常见问题

    JumpServer 各组件查询日志方法 # 默认持久化目录 /data/jumpserver ls -al /data/jumpserver/core/logs ls -al /data/jumps ...

  4. [EULAR文摘] 在总人群中监测ACPA能否预测早期关节炎

    标签: 类风湿关节炎; 抗CCP抗体; 预测因子; 病程演变 在总人群中监测ACPA能否预测早期关节炎 Verstappen SM, et al. EULAR 2015. Present ID: OP ...

  5. 基于C++的OpenGL 02 之着色器

    1. 概述 本文基于C++语言,描述OpenGL的着色器 环境搭建以及绘制流程可参考: 基于C++的OpenGL 01 之Hello Triangle - 当时明月在曾照彩云归 - 博客园 (cnbl ...

  6. 基于OpenGL绘制shp文件

    1. 引言 坐标数据是空间数据文件的核心,空间数据的数据量往往是很大的.数据可视化是GIS的一个核心应用,绘制海量的坐标数据始终是一个考验设备性能的难题,使用GPU进行绘制可有效减少CPU的负载,提升 ...

  7. postgresql 数据库 INSERT 或 UPDATE 大量数据时速度慢的原因分析

    前言 最近这段时间一直使用pg 数据库插入更新大量的数据,发现pg数据库有时候插入数据非常慢,这里我对此问题作出分析,找到一部分原因,和解决办法. 一 死元祖过多 提起pg数据库,由于他的构造,就不得 ...

  8. 四种语言刷算法之删除链表的倒数第 N 个结点

    力扣19. 删除链表的倒数第 N 个结点 1.C /**  * Definition for singly-linked list.  * struct ListNode {  *     int v ...

  9. TypeError: unsupported operand type(s) for |=: 'dict' and 'dict'

    原因:python3.9 支持对 dict 类型使用 |, 而较老的版本不支持 解决方案 :1. 用更新的 python 2. 把 | 操作替换成 {**d1, **d2} 来源:https://st ...

  10. pycharm软件基本使用python语法的注释变量的使用常量的使用变量的命名规范python的优化垃圾回收机制数据类型

    pycharm软件基本使用 1.pycharm基本的使用方法:1.点击file找到settings(设置)打开Appearance&Behavior点击Appearance看theme这个就是 ...