【go写数据结构】 线性表-双向循环链表

淡淡的烟草味﹌ 2022-12-12 04:53 295阅读 0赞

git地址:https://gitee.com/HappyTeemo/go\_for\_algorithm

  1. package my_list
  2. import (
  3. "fmt"
  4. "math"
  5. )
  6. //双向循环链表
  7. type DLinkList struct {
  8. Head *DNode
  9. Length int
  10. }
  11. type DNode struct {
  12. Data ElemType
  13. Next *DNode //直接后继指针
  14. Prior *DNode //直接前驱指针
  15. }
  16. //初始化列表
  17. func (l *DLinkList) InitList() {
  18. l.Head = new(DNode)
  19. l.Head.Next = l.Head //指向自己
  20. l.Head.Prior = l.Head //指向自己
  21. l.Length = 0
  22. }
  23. //清空列表(不会清除头结点)
  24. func (l *DLinkList) ClearList() {
  25. l.Head.Next = l.Head //指向自己
  26. l.Head.Prior = l.Head //指向自己
  27. l.Length = 0
  28. }
  29. //判断是否为空
  30. func (l *DLinkList) ListEmpty() bool {
  31. if l.Length == 0 {
  32. return true
  33. }
  34. return false
  35. }
  36. //获取长度
  37. func (l *DLinkList) ListLength() int {
  38. return l.Length
  39. }
  40. //查 index可以正 可以负 负表示往前找
  41. func (l *DLinkList) GetElem(index int, e *ElemType) bool {
  42. if l.Length == 0 {
  43. fmt.Println("获取失败,队列为空")
  44. return false
  45. }
  46. i := int(math.Abs(float64(index)))
  47. if index > MAXSIZE {
  48. index = index + 1 //跳过头结点
  49. } else if index < 0 {
  50. index = index - 1 //跳过头结点
  51. }
  52. j := 1
  53. q := l.Head
  54. if index > 0 {
  55. q = q.Next
  56. } else {
  57. q = q.Prior
  58. }
  59. for q != nil && j < i {
  60. if index > 0 {
  61. q = q.Next
  62. } else {
  63. q = q.Prior
  64. }
  65. j++
  66. }
  67. *e = q.Data
  68. return true
  69. }
  70. //按照元素进行查找,获取索引
  71. func (l *DLinkList) LocateElem(value ElemType) int {
  72. if l.Length == 0 {
  73. fmt.Println("获取失败,队列为空")
  74. return 0
  75. }
  76. j := 0
  77. q := l.Head.Next
  78. for q != nil {
  79. j++
  80. if q.Data == value {
  81. break
  82. }
  83. q = q.Next
  84. }
  85. if j >= MAXSIZE {
  86. return 0
  87. }
  88. return j
  89. }
  90. //按照索引进行插入数据 可以双向插入
  91. func (l *DLinkList) ListInsert(index int, value ElemType) bool {
  92. if l.Length == MAXSIZE { //满了
  93. fmt.Println("插入失败,队列已满")
  94. return false
  95. }
  96. //if index < 1 || index > l.Length+1 {
  97. // fmt.Println("插入失败,位置错误")
  98. // return false
  99. //}
  100. i := int(math.Abs(float64(index)))
  101. if index > MAXSIZE {
  102. index = index + 1 //跳过头结点
  103. } else if index < 0 {
  104. index = index - 1 //跳过头结点
  105. }
  106. j := 1
  107. cur := l.Head
  108. if index > 0 {
  109. cur = cur.Next
  110. } else {
  111. cur = cur.Prior
  112. }
  113. for cur != nil && j < i {
  114. if index > 0 {
  115. cur = cur.Next
  116. } else {
  117. cur = cur.Prior
  118. }
  119. j++
  120. }
  121. //新建节点,加入链表
  122. n := new(DNode)
  123. if index > 0 {
  124. n.Next = cur
  125. n.Prior = cur.Prior
  126. cur.Prior.Next = n
  127. cur.Prior = n
  128. } else {
  129. n.Next = cur.Next
  130. n.Prior = cur
  131. cur.Next.Prior = n
  132. cur.Next = n
  133. }
  134. n.Data = value
  135. l.Length++
  136. return true
  137. }
  138. //删
  139. func (l *DLinkList) ListDelete(index int, e *ElemType) bool {
  140. if l.Length == 0 {
  141. fmt.Println("获取失败,队列为空")
  142. return false
  143. }
  144. if index < 1 || index > l.Length {
  145. fmt.Println("获取失败,位置错误")
  146. return false
  147. }
  148. j := 1
  149. front := l.Head
  150. //找到索引的直接前驱
  151. for front.Next != nil && j < index {
  152. front = front.Next
  153. j++
  154. }
  155. if front.Next == nil || j > index {
  156. return false
  157. }
  158. //开始删除
  159. tmp := front.Next //记录要删除的
  160. *e = tmp.Data //返回删除节点的数据
  161. front.Next = tmp.Next //前驱节点直接指向后继节点,就跳过了要删除的节点
  162. tmp.Next.Prior = front.Prior
  163. //free(tmp)
  164. l.Length--
  165. return true
  166. }
  167. //输出
  168. func (l *DLinkList) Echo() {
  169. //遍历的写法
  170. curItem := l.Head.Next
  171. for i := 0; i < l.Length; i++ {
  172. fmt.Print(curItem.Data, " ")
  173. curItem = curItem.Next
  174. }
  175. fmt.Println()
  176. }
  177. func (l *DLinkList) Test() {
  178. fmt.Println("测试开始")
  179. my_list := new(DLinkList)
  180. my_list.InitList()
  181. for i := 1; i <= 10; i++ {
  182. my_list.ListInsert(i, ElemType(i*i+1))
  183. my_list.Echo()
  184. }
  185. fmt.Println("第5个这里插入256")
  186. my_list.ListInsert(5, 256)
  187. my_list.Echo()
  188. fmt.Println("第-5个这里插入256")
  189. my_list.ListInsert(-5, 256)
  190. my_list.Echo()
  191. my_list.ListInsert(199, 99)
  192. var e ElemType
  193. my_list.GetElem(my_list.ListLength()+1, &e)
  194. fmt.Println("最后一个的下一个:", e)
  195. my_list.ListDelete(1, &e)
  196. fmt.Println("删除头元素:", e)
  197. my_list.Echo()
  198. my_list.ListDelete(my_list.ListLength(), &e)
  199. fmt.Println("删除尾元素:", e)
  200. my_list.Echo()
  201. my_list.GetElem(6, &e)
  202. fmt.Println("获取第6个:", e)
  203. //fmt.Println("最后一个的下一个:", e.Next)
  204. fmt.Println("256的位置:", my_list.LocateElem(256))
  205. fmt.Println("长度:", my_list.ListLength())
  206. fmt.Println("开始清空")
  207. my_list.ClearList()
  208. if my_list.ListEmpty() {
  209. fmt.Println("已清空")
  210. my_list.Echo()
  211. }
  212. fmt.Println("测试完成")
  213. }

发表评论

表情:
评论列表 (有 0 条评论,295人围观)

还没有评论,来说两句吧...

相关阅读