單鏈表
定義
如果鏈表中的每個結點只包含一個指針,則該鏈表稱爲單鏈表
。
單鏈表結構如圖所示:
代碼實現
package SingleLinkling
import (
"fmt"
)
// 定義單鏈表接口
type SingleLink interface {
// 返回第一個數據結點
GetFirstNode() *SingleLinkNode
// 插入結點(頭插法)
InsertNodeFront(node *SingleLinkNode)
// 插入結點(尾插法)
InsertNodeBack(node *SingleLinkNode)
// 插入某結點前
InsertNodeValueFront(dest interface{}, node *SingleLinkNode) bool
// 插入某結點後
InsertNodeValueBack(dest interface{}, node *SingleLinkNode) bool
// 獲取指定索引上的結點
GetNodeAtIndex(index int) *SingleLinkNode
// 刪除結點
DeleteNode(dest *SingleLinkNode) bool
// 刪除指定索引上的結點
DeleteAtIndex(index int) bool
// 返回字符串
String() string
}
// 單鏈表
type SingleLinkList struct {
// 頭指針
head *SingleLinkNode
// 長度
length int
}
// 初始化單鏈表
func NewSingleLinkList() *SingleLinkList {
// 初始化頭結點
head := NewSingleLinkNode(nil)
return &SingleLinkList{
head: head,
length: 0,
}
}
// 獲取第一個數據結點
func (list *SingleLinkList) GetFirstNode() *SingleLinkNode {
return list.head.pNext
}
// 獲取指定索引上的結點
func (list *SingleLinkList) GetNodeAtIndex(index int) *SingleLinkNode {
// 索引越界
if index > list.length-1 || index < 0 {
return nil
}
// 備份頭結點
bak := list.head
// 向後循環
for index > -1 {
bak = bak.pNext
index--
}
return bak
}
// 頭部插入
func (list *SingleLinkList) InsertNodeFront(node *SingleLinkNode) {
// 空鏈表
if list.head == nil {
// 第一個數據結點設爲新結點
list.head.pNext = node
// 新結點指針指向nil
node.pNext = nil
list.length++
return
}
// 備份頭結點
bak := list.head
// 新結點的指針,指向原來的第一個數據結點
node.pNext = bak.pNext
// 頭結點指向新結點
bak.pNext = node
list.length++
return
}
// 尾部插入
func (list *SingleLinkList) InsertNodeBack(node *SingleLinkNode) {
// 空鏈表
if list.head == nil {
// 第一個數據結點設爲新結點
list.head.pNext = node
// 新結點指針指向nil
node.pNext = nil
list.length++
return
}
// 備份頭結點
bak := list.head
// 循環到鏈表末尾
for bak.pNext != nil {
bak = bak.pNext
}
// 終端結點的指針指向新結點
bak.pNext = node
list.length++
return
}
// 插入某結點前
func (list *SingleLinkList) InsertNodeValueFront(dest interface{}, node *SingleLinkNode) bool {
// 備份頭結點
bak := list.head
// 循環到末尾,直至找到目標結點
for bak.pNext != nil && bak.pNext.value != dest {
bak = bak.pNext
}
// 找到
if bak.pNext.value == dest {
// 目標結點的上一個數據結點的指針,賦值給新結點的指針
node.pNext = bak.pNext
// 目標結點的上一個數據結點的指針,指向新結點
bak.pNext = node
list.length++
return true
}
return false
}
// 插入某結點後
func (list *SingleLinkList) InsertNodeValueBack(dest interface{}, node *SingleLinkNode) bool {
// 備份頭結點
bak := list.head
// 循環到末尾,直至找到目標結點
for bak.pNext != nil && bak.pNext.value != dest {
bak = bak.pNext
}
// 找到
if bak.pNext.value == dest {
// 目標結點的指針賦值給新結點的指針
node.pNext = bak.pNext.pNext
// 目標結點的指針指向新結點
bak.pNext.pNext = node
list.length++
return true
}
return false
}
// 刪除結點
func (list *SingleLinkList) DeleteNode(dest *SingleLinkNode) bool {
// 備份頭結點
bak := list.head
// 循環到末尾,直至找到目標結點
for bak.pNext != nil && bak.pNext != dest {
bak = bak.pNext
}
// 找到
if bak.pNext == dest {
// 目前結點的指針賦值給目標結點的上一個數據結點的指針
bak.pNext = bak.pNext.pNext
list.length--
return true
}
return false
}
// 刪除指定索引上的結點
func (list *SingleLinkList) DeleteAtIndex(index int) bool {
// 索引越界
if index > list.length-1 || index < 0 {
return false
}
// 備份頭結點
bak := list.head
// 向後循環,找到前一個結點
for index > 0 {
bak = bak.pNext
index--
}
// 目前結點的指針賦值給目標結點的上一個數據結點的指針
bak.pNext = bak.pNext.pNext
list.length--
return true
}
// 獲取鏈表中間結點
func (list *SingleLinkList) GetMid() *SingleLinkNode {
// 鏈表只有一個結點
if list.head.pNext == nil {
return nil
}
phead1 := list.head
phead2 := list.head
for phead2 != nil && phead2.pNext != nil {
phead1 = phead1.pNext
phead2 = phead2.pNext.pNext
}
return phead1
}
// 鏈表反轉
func (list *SingleLinkList) ReverseList() {
// 鏈表爲空或者只有一個結點
if list.head == nil || list.head.pNext == nil {
return
}
// 前一個結點
var pre *SingleLinkNode
// 當前結點
cur := list.head.pNext
for cur != nil {
pre, cur, cur.pNext = cur, cur.pNext, pre
}
list.head.pNext = pre
}
// 返回字符串
func (list *SingleLinkList) String() string {
var listString string
// 頭結點
p := list.head
// 循環輸出
for p.pNext != nil {
listString += fmt.Sprintf("%v-->", p.pNext.value)
p = p.pNext
}
listString += fmt.Sprintf("nil")
return listString
}
時間複雜度
單鏈表,在讀數據時,時間複雜度爲O(n);
而在進行插入、刪除操作時,時間複雜度爲O(1)。