Go数据结构----双端插入新节点

从头部(尾部)开始某个位置前插入新节点

三种情况进行插入新节点:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BLBQrF4k-1684332357909)(C:\Users\27198\AppData\Roaming\Typora\typora-user-images\image-20230513151555431.png)]

// AddNodeFromHead 就是从头开始进行添加节点到N+1个元素之前
// N=0表示添加到第一个元素之前,表示新节点成为新的头部,
// N=1表示添加到第二个元素之前,以此类推
func (list *DoubleList) AddNodeFromHead(n int, v string) {
	list.lock.Lock()
	defer list.lock.Unlock()
	//首先进行相关判断,如果索引长度超过列表长度,一定找不到,直接panic
	if n != 0 && n >= list.len {
		panic("index out!!!")
	}
	//首先找到头节点
	node := list.head
	//然后依次往后进行遍历操作
	for i := 0; i < n; i++ {
		node = node.next
	}
	//创建新节点
	newNode := new(ListNode)
	newNode.value = v

	//然后进行节点插入操作
	//如果定位到的节点为空,表示列表为空,将新节点设置为新头部和新尾部
	//1.相当于情况1,第一种情况,判断定位到的节点 node 是否为空,如果为空,表明列表没有元素,将新节点设置为新头部和新尾部即可:
	if node.IsNil() {
		list.head = newNode
		list.tail = newNode
	} else {
		//定位到了节点,它的前驱就是头部的前驱
		pre := node.pre

		//2.如果定位到的节点前驱为nil,那么定位到的节点就是链表头部,需要换头部
		if pre.IsNil() {
			//将新节点连接在老头部之前
			newNode.next = node
			node.pre = newNode
			//新节点成为头部
			list.head = newNode

		} else {
			//第三种情况,
			//如果定位到的节点的前驱节点不为空,表明定位到的节点 node 不是头部节点,那么我们只需将新节点链接到节点 node 之前即可:
			pre.next = newNode
			newNode.next = pre

			//定位到的节点的后驱节点 node.next现在链接到新节点上
			node.next.pre = newNode
			newNode.next = node.next
		}
	}
	list.len = list.len + 1
}

// AddNodeFromTail 从尾部开始,添加节点到N+1个元素之后,N=0表示添加到第一个元素之后,表示新节点成为新的尾部,N=1,表示添加第二个元素之后,以此类推
func (list *DoubleList) AddNodeFromTail(n int, v string) {
	//加入并发锁
	list.lock.Lock()
	list.lock.Unlock()
	//先进行对应的判断,如果长度超过或等于列表超度,一定就找不到
	if n != 0 && n >= list.len {
		panic("index out")
	}

	//先找出尾部
	node := list.tail

	for i := 0; i < n; i++ {
		node = node.pre
	}
	//创建新节点的相关信息
	newNode := new(ListNode)
	newNode.value = v

	//如果定位到的节点为空,表示列表为空,将新节点设置为新头部和新尾部
	if node.IsNil() {
		list.head = newNode
		list.tail = newNode
	} else {
		next := node.next
		//如果定位到的节点后驱为nil,那么定位到的节点为链表尾部,就需要更换尾部
		if next.IsNil() {
			node.next = newNode
			newNode.pre = node
			list.tail = newNode
		} else {
			//将新节点插入到定位到的节点之后
			//新节点链接到定位到的节点之后
			newNode.pre = newNode
			node.next = newNode

			//定位到的节点的后驱节点连接到新节点之后
			newNode.next = next
			next.pre = newNode
		}
	}
	list.len = list.len + 1
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值