链表——初探,反转,删除

package linkedTabl

import (
	"fmt"
	"testing"
)

// 单向链表
type Node struct {
	Value int
	Next  *Node
}


// 双向链表
type DoubleNode struct {
	Value int
	Prev *DoubleNode
	Next *DoubleNode
}

func NewList(val ...int) *Node {
	if len(val) == 0 {
		return nil
	}

	p := &Node{
		Value: val[0],
		Next:  nil,
	}

	head := p

	for i := 1; i < len(val); i++ {
		p.Next = &Node{Value: val[i]}
		p = p.Next
	}
	return head
}

func (n *Node)String() string {
    val := ""
	for n != nil {
		val +="->"+fmt.Sprintf("%d",n.Value)
		n = n.Next
	}
	return val
}

// 单链表 和 双链表如何反转
func TestNode(t *testing.T)  {
	head := NewList(1,3,4,2,3,4,5,6,2,34,56,8)
	for p := head; p != nil; p = p.Next {
		fmt.Print(p.Value,"->")
	}
	fmt.Println()

	re := ReverseLinkedList(head)
	for p := re; p != nil; p = p.Next {
		fmt.Print(p.Value,"->")
	}
	fmt.Println()
}

func ReverseLinkedList(head *Node) *Node {
	var pre, next  *Node
	for head != nil {
		next = head.Next   // 记录下一个节点
		head.Next = pre    // 将当前节点 添加到prev 头部
		pre = head         // prev 指向头部
		head = next        // 当前节点指向下一个节点
	}
	return pre
}


func NewDoubleList(val ...int) *DoubleNode {
	if len(val) == 0 {
		return nil
	}

	p := &DoubleNode{
		Value: val[0],
		Prev : nil,
		Next:  nil,
	}

	head := p

	for i := 1; i < len(val); i++ {
		p.Next = &DoubleNode{
			Value: val[i],
			Prev :p,
		}
		p = p.Next
	}
	return head
}



// 单链表 和 双链表如何反转
func TestDoubleNode(t *testing.T)  {
	head := NewDoubleList(1,3,4,2,3,4,5,6,2,34,56,8)
	for p := head; p != nil; p = p.Next {
		fmt.Print(p.Value,"->")
	}
	fmt.Println()

	re := ReverseDoubleLinkedList(head)
	for p := re; p != nil; p = p.Next {
		fmt.Print(p.Value,"->")
	}
	fmt.Println()

	for re != nil {
		fmt.Print(re.Value, "->")
		re = re.Next
	}
	fmt.Println()
}



func ReverseDoubleLinkedList(head *DoubleNode) *DoubleNode  {
	var prev, next *DoubleNode
	for head != nil {
		next = head.Next

		head.Next = prev
		head.Prev = next
		prev = head

		head = next
	}
	return prev
}



func TestRemoveNodeValue(t *testing.T) {
	head := NewList(3,3,4,2,3,4,5,6,2,34,56,8)
	newHead := RemoveNodeValue(head,3)
	fmt.Println(newHead)
}

// 单链表和双链表 如何删除
// 删掉的节点有可能是头节点

func RemoveNodeValue(head *Node, num int) *Node {
	for head != nil {
		if head.Value != num {
			break
		}
		head = head.Next
	}
	fmt.Println(head)

	prev, cur := head, head
	for cur != nil {
	   if cur.Value == num {
		   prev.Next = cur.Next
	   }else {
		   prev = cur
	   }
	   cur = cur.Next
	}
	return head
}

func TestRemoveDoubleValue(t *testing.T) {
	head := NewDoubleList(3,3,4,2,3,4,5,6,2,34,56,8)
	tail := &DoubleNode{}
	for head = RemoveDoubleNodeValue(head,3); head != nil; head = head.Next {
		fmt.Print(head.Value,"->")
		if head.Next == nil {
			tail = head
		}
	}
	fmt.Println()
	for tail != nil {
		fmt.Print(tail.Value,"->")
		tail = tail.Prev 
	}
	fmt.Println()
}

func RemoveDoubleNodeValue(head *DoubleNode, num int) *DoubleNode {
	for head != nil {
		if head.Value != num {
			break
		}
		head = head.Next
	}
	head.Prev = nil


	prev, cur := head, head
	for cur != nil {
		if cur.Value == num {
			prev.Next = cur.Next
			if cur.Next != nil {
				cur.Next.Prev = prev
			}
		}else {
			prev = cur
		}
		cur = cur.Next
	}
	return head
}

// 删除时应防止内存泄露
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值