链表
链表是一种数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表中的节点可以按照任意顺序排列,它们通过指针相互连接起来。与数组不同,链表的节点不需要在内存中连续存储。链表通常用于需要频繁插入或删除元素的场景,因为其插入和删除的时间复杂度低。
单项链表
package main
import "fmt"
type Student struct {
Name string
age int
next *Student
//指向这个结构体的指针地址
}
func main() {
//头部结构体
var head Student
head.Name = "zhangsan"
head.age = 20
//第二个结构体
var stu1 Student
stu1.Name = "lisi"
stu1.age = 22
//头部指向第二个结构体指针地址
head.next = &stu1
//第三个结构体
var stu2 Student
stu2.Name = "wangwu"
stu2.age = 26
//第二个指向第三个结构体地址
stu1.next = &stu2
Rey(&head)
//定义结构体指针 从头部索引
//var a *Student = &head
}
func Rey(a *Student) {
//遍历输出链表中每一个结构体
//直到a不等于空,也就是next的下一跳为空时结束循环
for a != nil {
fmt.Println(*a)
a = a.next
//让a成为下一条的链表,如此循环,直到a为nil
}
}
输出结果
{zhangsan 20 0xc00011c3a0}
{lisi 22 0xc00011c3c0}
{wangwu 26 <nil>}
链表实现增删改查
package main
import (
"fmt"
)
type Head struct {
User string
next *Head //链表
}
func AddHead(h **Head) {
for i := 0; i < 10; i++ {
//生成一个新链表
var AddHead Head = Head{
User: fmt.Sprintf("node%d", i+1),
}
//新链表的下一跳指向h的地址
AddHead.next = *h
//将h的地址转换成新链表
*h = &AddHead
}
}
//输出链表,和上面写法一样
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{User: "张三"}
//调用头部添加的链表
AddHead(&head)
//从头部索引
Rey(head)
}
运行结果
{node10 0xc0000c2600}
{node9 0xc0000c25d0}
{node8 0xc0000c25a0}
{node7 0xc0000c2570}
{node6 0xc0000c2540}
{node5 0xc0000c2510}
{node4 0xc0000c24e0}
{node3 0xc0000c24b0}
{node2 0xc0000c2480}
{node1 0xc0000c2450}
{张三 <nil>}
尾添加链表
package main
import (
"fmt"
)
//链表的增删改查
//首先定义结构体
type Head struct {
User string
pwd string
next *Head //链表
}
//尾部添加
func AddTail(a *Head) {
for i := 0; i < 10; i++ {
var AddTail Head = Head{
User: fmt.Sprintf("node%d", i+1),
pwd: fmt.Sprintf("love%d", i),
}
a.next = &AddTail
a = &AddTail
}
}
//遍历链表
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
//让list变为下一结构体地址
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{
User: "张三",
pwd: "love789",
}
//从尾部添加的链表
AddTail(head)
//从头部索引
Rey(head)
}
从中间任意添加链表
package main
import (
"fmt"
)
//链表的增删改查
//首先定义结构体
type Head struct {
User string
pwd string
next *Head //链表
}
//头部添加
func AddHead(h **Head) {
for i := 0; i < 10; i++ {
var AddHead Head = Head{
User: fmt.Sprintf("node%d", i+1),
pwd: fmt.Sprintf("love%d", i),
}
AddHead.next = *h
*h = &AddHead
}
}
//任意位置添加链表
func AddRandom(a *Head, n *Head) {
for a != nil {
if a.User == "node2" {
//切换next
n.next = a.next
a.next = n
}
a = a.next
}
}
//遍历链表
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
//让list变为下一结构体地址
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{
User: "张三",
pwd: "love789",
}
定义一个中间连接的链表块
var NewHead = &Head{
User: "王五",
pwd: "123456",
}
//调用头部添加的链表
AddHead(&head)
//调用任意位置添加的链表
AddRandom(head, NewHead)
//从头部索引
Rey(head)
}
运行结果
{node10 love9 0xc000078660}
{node9 love8 0xc000078630}
{node8 love7 0xc000078600}
{node7 love6 0xc0000785d0}
{node6 love5 0xc0000785a0}
{node5 love4 0xc000078570}
{node4 love3 0xc000078540}
{node3 love2 0xc000078510}
{node2 love1 0xc0000784b0}
{王五 123456 0xc0000784e0}
{node1 love0 0xc000078480}
{张三 love789 <nil>}
修改链表方案1
package main
import (
"fmt"
)
//链表的增删改查
//首先定义结构体
type Head struct {
User string
pwd string
next *Head //链表
}
//头部添加
func AddHead(h **Head) {
for i := 0; i < 10; i++ {
var AddHead Head = Head{
User: fmt.Sprintf("node%d", i+1),
pwd: fmt.Sprintf("love%d", i),
}
AddHead.next = *h
*h = &AddHead
}
}
//任意位置添加链表
func AddRandom(a *Head, n *Head) {
for a != nil {
if a.User == "node2" {
//切换next
n.next = a.next
a.next = n
}
a = a.next
}
}
func UpdataHead(u *Head, name string, n *Head) {
var up = u
for u != nil {
if u.User == name {
up.next = u.next
break
}
// up = u
// u = u.next
if u.User == name {
n.next = u.next
u.next = n
}
up = u
u = u.next
}
}
//遍历链表
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
//让list变为下一结构体地址
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{
User: "张三",
pwd: "love789",
}
//定义一个中间连接的链表块
var NewHead = &Head{
User: "王五",
pwd: "123456",
}
//调用头部添加的链表
AddHead(&head)
//调用任意位置添加的链表
AddRandom(head, NewHead)
//修改
UpdataHead(head, "node3", NewHead)
//从头部索引
Rey(head)
}
修改链表方案2
package main
import (
"fmt"
)
//链表的增删改查
//首先定义结构体
type Head struct {
User string
pwd string
next *Head //链表
}
//头部添加
func AddHead(h **Head) {
for i := 0; i < 10; i++ {
var AddHead Head = Head{
User: fmt.Sprintf("node%d", i+1),
pwd: fmt.Sprintf("love%d", i),
}
AddHead.next = *h
*h = &AddHead
}
}
//任意位置添加链表
func AddRandom(a *Head, n *Head) {
for a != nil {
if a.User == "node2" {
//切换next
n.next = a.next
a.next = n
}
a = a.next
}
}
//修改链表
func modifyStudentNode(head *Head, name string, n *Head) {
temp := head
//思路:
//1.找到要修改的结点的no,和temp.next.no作比较
for temp != nil {
if temp.next.User == name {
//说明我们已经找到这个要修改的结点了
head.next = temp.next
temp.next = n
break
}
temp = temp.next
head = temp
}
}
//遍历链表
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
//让list变为下一结构体地址
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{
User: "张三",
pwd: "love789",
}
//定义一个中间连接的链表块
var NewHead = &Head{
User: "王五",
pwd: "123456",
}
//调用头部添加的链表
AddHead(&head)
//调用任意位置添加的链表
AddRandom(head, NewHead)
modifyStudentNode(head, "node2", NewHead)
//从头部索引
Rey(head)
}
修改结果
{node10 love9 0xc0000c2630}
{node9 love8 0xc0000c2600}
{node8 love7 0xc0000c25d0}
{node7 love6 0xc0000c25a0}
{node6 love5 0xc0000c2570}
{node5 love4 0xc0000c2540}
{node4 love3 0xc0000c2510}
{node3 love2 0xc0000c2480}
{王五 123456 0xc0000c24b0}
{node1 love0 0xc0000c2450}
删除链表
package main
import (
"fmt"
)
//链表的增删改查
//首先定义结构体
type Head struct {
User string
pwd string
next *Head //链表
}
//头部添加
func AddHead(h **Head) {
for i := 0; i < 10; i++ {
var AddHead Head = Head{
User: fmt.Sprintf("node%d", i+1),
pwd: fmt.Sprintf("love%d", i),
}
AddHead.next = *h
*h = &AddHead
}
}
//删除链表
func deleteHead(d *Head) {
var del = d
for d != nil {
if d.User == "node5" {
del.next = d.next
break
}
del = d
d = d.next
}
}
//遍历链表
func Rey(list *Head) {
for list != nil {
fmt.Println(*list)
//让list变为下一结构体地址
list = list.next
}
}
func main() {
//头部链表
var head *Head = &Head{
User: "张三",
pwd: "love789",
}
//调用头部添加的链表
AddHead(&head)
//调用删除
deleteHead(head)
//从头部索引
Rey(head)
}
运行结果
{node10 love9 0xc000078630}
{node9 love8 0xc000078600}
{node8 love7 0xc0000785d0}
{node7 love6 0xc0000785a0}
{node6 love5 0xc000078540}
{node4 love3 0xc000078510}
{node3 love2 0xc0000784e0}
{node2 love1 0xc0000784b0}
{node1 love0 0xc000078480}
{张三 love789 <nil>}
二叉树
满足以下两个条件的树就是二叉树:
1.本身是有序树;
2.树中包含的各个节点的度不能超过2,即只能是0、1或者2;
前序遍历二叉树——根左右
package main
import "fmt"
//定义结构体
type Student struct {
Name string
Age int
Score float32
left *Student
right*Student
}
/*二叉树*/
func main(){
//根节点
var root student
root.Name = "root"
root.Age = 10
root. Score = 90
//左子树
var left1 student
left1.Name = "left1"
left1.Age = 20
left1.Score = 80
root.left = &left1
//右子树
var right1 student
right1. Name = "right1”
right1. Age = 30
right1. Score - 70
root.right - &right1
//二级左子树
var left2 Student
left2.Name = "left2”
left2.Age = 40
left2.Score = 60
left1.left = &left2
//调用遍历函数
Req(&root)
}
//递归算法遍历整颗二叉树
func Req(rootl *student){
if root == nil {
return
}
fmt.Println(root)
//遍历左子树
Req(root.left)
//遍历右子树
Req(root.right)
}
运行结果
&{root 10 90 exce880764be exce880764ee}
&{left1 28 80 exce88876510<nil>}
&{left2 40 60 <nil><nil>}
&{right1 30 70 <nil> <nil>}
中序遍历——左根右
func Req(rootl *student){
if root == nil {
return
}
//遍历左子树
Req(root.left)
fmt.Println(root)
//遍历右子树
Req(root.right)
}
后序遍历——左右根
func Req(rootl *student){
if root == nil {
return
}
//遍历左子树
Req(root.left)
//遍历右子树
Req(root.right)
fmt.Println(root)
}