数据结构与算法 — 链表常见操作(Golang)

1 代码实现

代码:

package main

import (
	"errors"
	"fmt"
)

type Node struct {
	Data int
	Next *Node //需要使用指针类型,因为只有指针类型才能被修改
}

var Head *Node
var Size int

/**
查找结点
*/
func getNode(index int) (currentNode *Node, err error) {
	if index < 0 || index >= Size {
		return nil, errors.New("超出链表范围")
	}
	tempNode := Head
	for i := 0; i < index; i++ {
		tempNode = tempNode.Next
	}
	return tempNode, nil
}

func InsertElement(data, index int) error {
	if index < 0 || index > Size {
		return errors.New("超出链表范围")
	}
	insertNode := &Node{
		Data: data,
		Next: nil,
	}

	if index == 0 { //在头部插入
		insertNode.Next = Head
		Head = insertNode
	} else if index == Size { //在尾部插入
		preNode, err := getNode(index - 1) //获取尾结点的前一个结点
		if err != nil {
			return errors.New("超出链表范围")
		}
		preNode.Next = insertNode
	} else { //中间插入
		preNode, err := getNode(index - 1) //获取尾结点的前一个结点
		if err != nil {
			return errors.New("超出链表范围")
		}
		nextNode := preNode.Next
		preNode.Next = insertNode
		insertNode.Next = nextNode
	}
	Size++
	return nil
}

func DeleteElement(index int) (deletedNode *Node, err error) {
	if index < 0 || index >= Size {
		return nil, errors.New("超出链表范围")
	}
	if index == 0 { //删除头节点
		nextNode := Head.Next //获取头节点的下一个节点
		Head.Next = nil       //将头节点的Next指向nil
		deletedNode = Head    //返回删除的头节点
		Head = nextNode       //将nextNode设置为新的头节点
	} else if index == Size-1 { //删除尾节点
		preNode, err := getNode(index - 1)
		if err != nil {
			return nil, errors.New("超出链表范围")
		}
		deletedNode = preNode.Next
		preNode.Next = nil
	} else { //删除中间节点
		preNode, err := getNode(index - 1)
		if err != nil {
			return nil, errors.New("超出链表范围")
		}
		deletedNode = preNode.Next
		nextNode := deletedNode.Next
		deletedNode.Next = nil
		preNode.Next = nextNode
	}
	Size--
	return deletedNode, nil
}

func ShowNode() {
	tempNode := Head
	index := 1
	for tempNode.Next != nil {
		fmt.Println("第 ", index, " 个节点的数据 :", tempNode.Data)
		tempNode = tempNode.Next
		index++
	}
	//fmt.Println("尾节点的数据 :", tempNode.Data)
	fmt.Println("第 ", index, " 个节点(尾结点)的数据 :", tempNode.Data)
}

func main() {
	InsertElement(3, 0)
	InsertElement(7, 1)
	InsertElement(9, 2)
	InsertElement(5, 3)
	InsertElement(6, 1)
//	数据的顺序:3、6、7、9、5

	//DeleteElement(0)
	//DeleteElement(1)
	//DeleteElement(4)
	ShowNode()

}

2 时间/空间复杂度

参考1:数组、链表、跳表的时间复杂度和空间复杂度

2.1 插入的时间/空间复杂度

头插入:时间复杂度为O(1),空间复杂度为O(n)。
尾插入:时间复杂度为O(1),空间复杂度为O(n)。
中间插入:时间复杂度为O(1),空间复杂度为O(n);

2.2 删除的时间/空间复杂度

头部删除:时间复杂度为O(1),空间复杂度为O(n)。
尾部删除:时间复杂度为O(1),空间复杂度为O(n)。
中间删除:时间复杂度为O(1),空间复杂度为O(n);

2.3 查找的时间/空间复杂度

查找的时间复杂度为O(n),假设每个节点所占空间的大小为1,空间复杂度为O(n)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值