写在前面
最近在复习数据结构,尝试用go实现了下单链表和双向循环链表。(详细内容在注释里面)仅供参考,有错误的话,希望大家能指出。
单链表
链表结构
// ListNode 链表的数据结构
type ListNode struct {
Data interface{}
NextNode *ListNode
}
创建链表
// creatHead 头插法实现单链表 [带头节点]
func (l *ListNode) creatHead(n int) *ListNode {
if n < 0 {
return nil
}
for i := 0; i < n;i++ {
newNode := new(ListNode)
// 假设传入数据
newNode.Data = i
// 将新节点的next指向l
newNode.NextNode = l.NextNode
// l的next指向新节点,从而调到首部
l.NextNode = newNode
}
return l
}
// createTail 尾插法实现单链表
func (l *ListNode) createTail(n int) *ListNode {
if n < 0{
return nil
}
tmp := l
for i := 0; i < n; i++ {
newNode := new(ListNode)
newNode.Data = i
// tmp的next指向新结点
tmp.NextNode = newNode
// tmp移动到新节点
tmp = newNode
}
return l
}
插入结点
// insertNode 插入新节点
func (l *ListNode) insertNode(pos int,data interface{}) *ListNode{
if pos < 0{
return nil
}
// 1.找到要插入位置的前一个位置
tmp := l
for i := 0; i < pos-1; i-- {
tmp = tmp.NextNode
}
// 2.将新节点的next指向tmp.next
newNode := new(ListNode)
newNode.Data = data
newNode.NextNode = tmp.NextNode
// 3.将前一个位置的next执行新结点
tmp.NextNode = newNode
return l
}
删除结点
// delNode 删除结点
func (l *ListNode) delNode(pos int) *ListNode {
if pos < 0{
return nil
}
if pos == 1{
delNote := l.NextNode
l.NextNode = delNote.NextNode
delNote.NextNode = nil
return l
}
// 1.找到要删除位置的前一个位置
tmp := l
for i := 0; i < pos-1; i++ {
tmp = tmp.NextNode
}
// 2.暂存要删除的结点
delNote := tmp.NextNode
// 3.将前一个结点指向要删除结点的next
tmp.NextNode = delNote.NextNode
// 4.释放要删除的结点
delNote.NextNode = nil
return l
}
双向循环链表
结构
// Ring 实现循环链表
type Ring struct {
pre *Ring // 前区结点
next *Ring // 后继结点
data interface{} // 值
}
初始化
// initCircle 初始化循环链表。前驱和后继都指向自己
func (r *Ring) initCircle() *Ring{
r.next = r
r.pre = r
return r
}
创建
// createList 创建一个新的循环链表
func createList(n int) *Ring {
if n <= 0{
return nil
}
r := new(Ring)
r.data = 0
list := r
for i := 1; i < n; i++ {
tmp := new(Ring)
tmp.data = i
tmp.pre = list
list.next = tmp
list = list.next
}
list.next = r
r.pre = list
return r
}
获取结点
// 获取前驱结点
func (r *Ring) getPrev() *Ring{
return r.pre
}
// 获取后继结点
func (r *Ring) getNext() *Ring {
return r.next
}
获取指定结点
// 获取指定的结点
func (r *Ring) getSelect(n int) *Ring {
tmp := r
for i := 0; i < n;i++ {
tmp = tmp.next
}
return tmp
}
添加结点
func (r *Ring) addNode(n int,data interface{}) *Ring{
tmp := r
for i := 0; i < n-1;i++ {
tmp = tmp.next
}
newNode := new(Ring)
newNode.data = data
// 新节点的next指向tmp的next
newNode.next = tmp.next
// 新节点的前去结点指向tmp
newNode.pre = tmp
// 当前结点的next指向新节点
tmp.next = newNode
// tmp.next的前驱结点指向新节点
tmp.next.pre = newNode
return r
}
删除结点
func (r *Ring) delNode(n int) *Ring{
if n < 0 {
return nil
}
tmp := r
// 找到要删除结点的前一个结点
for i := 0; i < n-1;i++ {
tmp = tmp.next
}
// 找到要删除的结点
delNode := tmp.next
// 将前一个结点的next指向要删除结点的next
tmp.next = delNode.next
// 将要删除结点后面的前驱结点指向tmp
delNode.next.pre = tmp
// 释放要删除的结点
delNode.pre = nil
delNode.next = nil
return r
}
参考的是之前用C写的数据结构的代码,功能是实现了。不知道使用go实现过程中有哪些地方和C不同。私下还需要去学习下。