• go语言|数据结构:单链表(3)刷题实战


    目录

    单链表——刷题实战

    任意类型的数据域

    实例01

    快慢指针

    实例02

    反转链表

    实例03

    实例04

    交换节点

    实例05


    单链表——刷题实战

    任意类型的数据域

    之前的链表定义数据域都是整型int,如果需要不同类型的数据就要用到 interface{}。

    空接口 interface{}
      对于描述起不到任何的作用(因为它不包含任何的method),但interface{}在需要存储任意类型的数值的时候相当有用,因为它可以存储任意类型的数值。
      一个函数把interface{}作为参数,那么它可以接受任意类型的值作为参数;如果一个函数返回interface{},那么也就可以返回任意类型的值,类似于C语言的void*类型。

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func (list *List) push(value interface{}) {
    11. node := &Node{data: value}
    12. p := list.head
    13. if p != nil {
    14. for p.next != nil {
    15. p = p.next
    16. }
    17. p.next = node
    18. } else {
    19. list.head = node
    20. }
    21. }
    22. func (list *List) travel() {
    23. p := list.head
    24. for p != nil {
    25. fmt.Print(p.data)
    26. p = p.next
    27. if p != nil {
    28. fmt.Print("->")
    29. }
    30. }
    31. fmt.Println("")
    32. }
    33. func main() {
    34. node := new(List)
    35. node.push("abc")
    36. node.push(3.142)
    37. node.push('a')
    38. node.push(3 + 4i)
    39. node.push([]int{1, 2, 3})
    40. node.push([8]byte{'a', 3: 'd'})
    41. node.push(Node{1, &Node{2, nil}}.data)
    42. node.push(Node{1, &Node{2, nil}}.next)
    43. node.travel()
    44. }
    45. /*输出:
    46. abc->3.142->97->(3+4i)->[1 2 3]->[97 0 0 100 0 0 0 0]->1->&{2 }
    47. */

    实例01

    把字串中汉字除外的所有字符逐个存入链表,且数字以整型保存。 

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func (list *List) push(value interface{}) {
    11. node := &Node{data: value}
    12. p := list.head
    13. if p != nil {
    14. for p.next != nil {
    15. p = p.next
    16. }
    17. p.next = node
    18. } else {
    19. list.head = node
    20. }
    21. }
    22. func (list *List) travel() {
    23. p := list.head
    24. for p != nil {
    25. fmt.Print(p.data)
    26. p = p.next
    27. if p != nil {
    28. fmt.Print("->")
    29. }
    30. }
    31. fmt.Println("")
    32. }
    33. func main() {
    34. node := new(List)
    35. str := "Golang数据结构123:单链表0789"
    36. for _, s := range str {
    37. if s >= 48 && s < 58 {
    38. node.push(s - 48)
    39. } else if s < 128 {
    40. node.push(string(s))
    41. }
    42. }
    43. node.travel()
    44. }
    45. /*输出:
    46. G->o->l->a->n->g->1->2->3->:->0->7->8->9
    47. */

    快慢指针

    给单链表设置2个指针,其中一个指针先移动n个节点,然后同时移动这2个指针,那么当先移动的指针到达尾部时,后移动的那个指针就是倒数第 n 个节点。先移动的指针称“快指针”,后出发的指针称“慢指针”,其实一样“快”只是出发有先后。

    实例02

    删除链表中倒数第 n 个结点

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func (list *List) removNthBack(n int) {
    11. if n > list.size() {
    12. panic("range error: n <= List's size")
    13. }
    14. var fast, slow *Node
    15. head := list.head
    16. fast = head
    17. slow = head
    18. for i := 0; i < n; i++ {
    19. fast = fast.next
    20. }
    21. if fast == nil {
    22. list.head = head.next
    23. return
    24. }
    25. for fast.next != nil {
    26. fast = fast.next
    27. slow = slow.next
    28. }
    29. slow.next = slow.next.next
    30. }
    31. func removNthBack(list *List, n int) *List {
    32. if n > list.size() {
    33. panic("range error: n <= List's size")
    34. }
    35. var fast, slow *Node
    36. head := list.head
    37. fast = head
    38. slow = head
    39. for i := 0; i < n; i++ {
    40. fast = fast.next
    41. }
    42. if fast == nil {
    43. list.head = head.next
    44. return list
    45. }
    46. for fast.next != nil {
    47. fast = fast.next
    48. slow = slow.next
    49. }
    50. slow.next = slow.next.next
    51. return list
    52. }
    53. func (list *List) push(value interface{}) {
    54. node := &Node{data: value}
    55. p := list.head
    56. if p != nil {
    57. for p.next != nil {
    58. p = p.next
    59. }
    60. p.next = node
    61. } else {
    62. list.head = node
    63. }
    64. }
    65. func (list *List) size() int {
    66. length := 0
    67. for p := list.head; p != nil; p = p.next {
    68. length++
    69. }
    70. return length
    71. }
    72. func (list *List) travel() {
    73. p := list.head
    74. for p != nil {
    75. fmt.Print(p.data)
    76. p = p.next
    77. if p != nil {
    78. fmt.Print("->")
    79. }
    80. }
    81. fmt.Println("")
    82. }
    83. func main() {
    84. lst := new(List)
    85. str := "12309"
    86. for _, s := range str {
    87. lst.push(s - 48)
    88. }
    89. lst.travel()
    90. lst.removNthBack(3)
    91. lst.travel()
    92. lst = removNthBack(lst, 3)
    93. lst.travel()
    94. lst.removNthBack(2)
    95. lst.travel()
    96. //lst.removNthBack(10) //panic error
    97. lst.removNthBack(2)
    98. lst.travel()
    99. lst.removNthBack(1)
    100. lst.travel()
    101. //lst.removNthBack(1) //panic error
    102. }
    103. /*输出:
    104. 1->2->3->0->9
    105. 1->2->0->9
    106. 1->0->9
    107. 1->9
    108. 9
    109. */

    反转链表

    遍历一个链表,每个结点用头插法相接的新链表就是原链表的反转结果。

    实例03

    反转整个链表

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func (list *List) reverse() {
    11. res := &List{}
    12. for p := list.head; p != nil; p = p.next {
    13. node := &Node{p.data, nil}
    14. node.next = res.head
    15. res.head = node
    16. }
    17. list.head = res.head
    18. }
    19. func (list *List) pushHead(value interface{}) {
    20. node := &Node{data: value}
    21. node.next = list.head
    22. list.head = node
    23. }
    24. func (list *List) build(lst []interface{}) {
    25. for i := len(lst) - 1; i >= 0; i-- {
    26. node := &Node{data: lst[i]}
    27. node.next = list.head
    28. list.head = node
    29. }
    30. }
    31. func (list *List) clear() {
    32. list.head = nil
    33. }
    34. func (list *List) travel() {
    35. p := list.head
    36. for p != nil {
    37. fmt.Print(p.data)
    38. p = p.next
    39. if p != nil {
    40. fmt.Print("->")
    41. }
    42. }
    43. fmt.Println("")
    44. }
    45. func main() {
    46. lst := new(List)
    47. for n := 5; n > 0; n-- {
    48. lst.pushHead(n)
    49. }
    50. lst.travel()
    51. lst.reverse()
    52. lst.travel()
    53. lst.clear()
    54. lst.build([]interface{}{6.13, "/", 100000, "Hann", 1.0e-5})
    55. lst.travel()
    56. lst.reverse()
    57. lst.travel()
    58. }
    59. /*输出:
    60. 1->2->3->4->5
    61. 5->4->3->2->1
    62. 6.13->/->100000->Hann->1e-05
    63. 1e-05->Hann->100000->/->6.13
    64. */

    实例04

    反转链表的其中一段,反转从第m个结点到n个结点(其中0

    Input: 1->2->3->4->5->nil, m = 2, n = 4
    Output: 1->4->3->2->5->nil

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func reverseBetween(list *List, m int, n int) *List {
    11. list = list.Copy()
    12. head := list.head
    13. if head == nil || m >= n {
    14. return list
    15. }
    16. if m < 1 { //防止范围左端超限
    17. m = 1
    18. }
    19. node := &Node{0, head}
    20. p := node
    21. for i := 0; p.next != nil && i < m-1; i++ {
    22. p = p.next
    23. }
    24. if p.next == nil {
    25. return list
    26. }
    27. cur := p.next
    28. for i := 0; i < n-m && cur.next != nil; i++ {
    29. //由cur.next != nil防止范围右端超限
    30. tmp := p.next
    31. p.next = cur.next
    32. cur.next = cur.next.next
    33. p.next.next = tmp
    34. }
    35. list.head = node.next
    36. return list
    37. }
    38. func (list *List) reverseBetween(m int, n int) {
    39. head := list.head
    40. if head == nil || m >= n {
    41. return
    42. }
    43. if m < 1 { //防止范围左端超限
    44. m = 1
    45. }
    46. node := &Node{0, head}
    47. p := node
    48. for i := 0; p.next != nil && i < m-1; i++ {
    49. p = p.next
    50. }
    51. if p.next == nil {
    52. return
    53. }
    54. cur := p.next
    55. for i := 0; i < n-m && cur.next != nil; i++ {
    56. //由cur.next != nil防止范围右端超限
    57. tmp := p.next
    58. p.next = cur.next
    59. cur.next = cur.next.next
    60. p.next.next = tmp
    61. }
    62. list.head = node.next
    63. }
    64. func (list *List) pushHead(value interface{}) {
    65. node := &Node{data: value}
    66. node.next = list.head
    67. list.head = node
    68. }
    69. func (list *List) build(lst []interface{}) {
    70. for i := len(lst) - 1; i >= 0; i-- {
    71. node := &Node{data: lst[i]}
    72. node.next = list.head
    73. list.head = node
    74. }
    75. }
    76. func (list *List) Copy() *List {
    77. p := list.head
    78. res := &List{}
    79. if p != nil {
    80. node := &Node{p.data, nil}
    81. q := node
    82. for p = p.next; p != nil; p = p.next {
    83. q.next = &Node{p.data, nil}
    84. q = q.next
    85. }
    86. res.head = node
    87. }
    88. return res
    89. }
    90. func (list *List) travel() {
    91. p := list.head
    92. for p != nil {
    93. fmt.Print(p.data)
    94. p = p.next
    95. if p != nil {
    96. fmt.Print("->")
    97. }
    98. }
    99. fmt.Println("")
    100. }
    101. func main() {
    102. list1 := new(List)
    103. list2 := new(List)
    104. for n := 5; n > 0; n-- {
    105. list1.pushHead(n)
    106. }
    107. list1.travel()
    108. list2 = reverseBetween(list1, 2, 4)
    109. list2.travel()
    110. list2 = reverseBetween(list1, 2, 3)
    111. list2.travel()
    112. list2 = reverseBetween(list1, 2, 5)
    113. list2.travel()
    114. list2 = reverseBetween(list1, 2, 6)
    115. list2.travel()
    116. list2 = reverseBetween(list1, 1, 6)
    117. list2.travel()
    118. list2 = reverseBetween(list1, 0, 3)
    119. list2.travel()
    120. list1.reverseBetween(1, 3)
    121. list1.travel()
    122. }
    123. /*输出:
    124. 1->2->3->4->5
    125. 1->4->3->2->5
    126. 1->3->2->4->5
    127. 1->5->4->3->2
    128. 1->5->4->3->2
    129. 5->4->3->2->1
    130. 3->2->1->4->5
    131. 3->2->1->4->5
    132. */

    交换节点

    实例05

    链表的相邻节点两两交换位置

    Given 1->2->3->4, you should return the list as 2->1->4->3.

    1. package main
    2. import "fmt"
    3. type Node struct {
    4. data interface{}
    5. next *Node
    6. }
    7. type List struct {
    8. head *Node
    9. }
    10. func (list *List) swapPairs() {
    11. p := list.head
    12. if p == nil || p.next == nil {
    13. return
    14. }
    15. head := p.next
    16. var node, node2 *Node
    17. for p.next != nil {
    18. cur := p.next
    19. if node != nil && node.next != nil {
    20. node.next = cur
    21. }
    22. if p.next.next != nil {
    23. node2 = p.next.next
    24. }
    25. if p.next.next != nil {
    26. p.next = node2
    27. } else {
    28. p.next = nil
    29. }
    30. cur.next = p
    31. node = p
    32. if p.next != nil {
    33. p = node2
    34. }
    35. }
    36. list.head = head
    37. }
    38. func swapPairs(list *List) *List {
    39. list = list.Copy()
    40. p := list.head
    41. if p == nil || p.next == nil {
    42. return list
    43. }
    44. head := p.next
    45. var node, node2 *Node
    46. for p.next != nil {
    47. cur := p.next
    48. if node != nil && node.next != nil {
    49. node.next = cur
    50. }
    51. if p.next.next != nil {
    52. node2 = p.next.next
    53. }
    54. if p.next.next != nil {
    55. p.next = node2
    56. } else {
    57. p.next = nil
    58. }
    59. cur.next = p
    60. node = p
    61. if p.next != nil {
    62. p = node2
    63. }
    64. }
    65. list.head = head
    66. return list
    67. }
    68. func (list *List) Copy() *List {
    69. p := list.head
    70. res := &List{}
    71. if p != nil {
    72. node := &Node{p.data, nil}
    73. q := node
    74. for p = p.next; p != nil; p = p.next {
    75. q.next = &Node{p.data, nil}
    76. q = q.next
    77. }
    78. res.head = node
    79. }
    80. return res
    81. }
    82. func (list *List) build(lst []interface{}) {
    83. for i := len(lst) - 1; i >= 0; i-- {
    84. node := &Node{data: lst[i]}
    85. node.next = list.head
    86. list.head = node
    87. }
    88. }
    89. func (list *List) travel() {
    90. p := list.head
    91. for p != nil {
    92. fmt.Print(p.data)
    93. p = p.next
    94. if p != nil {
    95. fmt.Print("->")
    96. }
    97. }
    98. fmt.Println("")
    99. }
    100. func main() {
    101. list1 := new(List)
    102. list2 := new(List)
    103. list1.build([]interface{}{1, 2, 3, 4, 5, 6})
    104. list1.travel()
    105. list2 = swapPairs(list1)
    106. list2.travel()
    107. list2 = &List{&Node{0, nil}}
    108. list2.head.next = list1.Copy().head
    109. list2.travel()
    110. list2.swapPairs()
    111. list2.travel()
    112. }
    113. /*输出:
    114. 1->2->3->4->5->6
    115. 2->1->4->3->6->5
    116. 0->1->2->3->4->5->6
    117. 1->0->3->2->5->4->6
    118. */

     

  • 相关阅读:
    Dubbo线程池
    SpringBoot激活profiles的几种方式
    QImage
    α-SRHLA
    mysql的基本知识点
    Linux搭建zookeeper与kafka集群配置
    C语言程序设计笔记(浙大翁恺版) 第五周:循环控制
    Java实现简单图书操作系统思路讲解
    SQL查询优化---单表使用索引及常见索引失效优化
    DSP-FIR滤波器设计
  • 原文地址:https://blog.csdn.net/boysoft2002/article/details/126490925