This is a creation in Article, where the information may have evolved or changed.
Golang and common operation of chain list, data Structure series original: Flaviocopes.com, translation has been authorized by the author.
Objective
The structure of a linked list is similar to an array, but the cost of inserting an element is much smaller than the array, because inserting an element in an array requires that all elements behind the insertion position be moved back one position, and that the deleted elements are all moved forward.
Arrays store elements sequentially in memory cells (statically allocated memory), while linked lists are stored in fragmented memory by pointers in elements (dynamically allocating memory)
There is an obvious drawback to a linked list: When looking for an element, you do not know the address of the element in the list, and you need to go through the entire list from the first element.
Linked list structure
Basic operation:
1 2 3 4 5 6 7 8 |
Append (t) //appends the element T to the tail of the linked list insert (I, T) //at position i insert element t removeat (i) //remove element of position I span> indexof (t) //returns the position of element T IsEmpty (L) //l is empty linked list returns true size () //returns the length of the linked list string () //returns the string representation of the linked list head () span class= "comment" >//returns the first node of the list to iterate the list |
I used Genny to create a generic type: ItemLinkedList
to allow the list to store elements of any data type. This can separate the implementation of the linked list from the data that is stored, and the implementation of the linked list is highly encapsulated.
Code implementation
1 2 3 4 5 6 7 8 9 Ten One A - - the - - - + - + A at - - - - - in - to + - the * $ Panax Notoginseng - the + A the + - $ $ - - the - Wuyi the - Wu - About $ - - - A + the - $ the the the the - in the the About the the the + - the Bayi the the - - the the the the - the the the 94 the the the 98 About - 101 102 103 104 the 106 107 108 109 the 111 the 113 the the the 117 118 119 - 121 122 123 124 the 126 127 - 129 the 131 the 133 134 135 136 137 138 139 $ 141 142 143 144 145 146 147 148 149 Max 151 the 153 154 155 156 157 158 159 the 161 162
|
//LinkedList package creates a itemlinkedlist linked list for an element of Item type Package linkedlist
Import ( "Github.com/cheekybits/genny/generic" "Sync" "FMT" )
type Item generic. Type
type Node struct { content Item Next *node }
type itemlinkedlist struct { Head *node size int lock Sync. Rwmutex }
//Append element at end of list func (list *itemlinkedlist) Append(t Item) { List.lock.Lock () NewNode: = node{t, nil}
//Find and append if list.head = = Nil { //empty list first APPEND element List.head = &newnode } Else { Curnode: = List.head //Traverse list, find tail node For { if curnode.next = = Nil { Break } Curnode = Curnode.next } Curnode.next = &newnode }
//Append back list length +1 list.size++ List.lock.Unlock () }
//Insert the specified element at the specified position in the list func (list *itemlinkedlist) Insert(i int, T Item) Error { List.lock.Lock () defer list.lock.Unlock () If i < 0 | | i > list.size { return to FMT. Errorf ("Index%d out of Bonuds", i) } NewNode: = node{t, nil}
if i = = 0 { //INSERT into the list header Newnode.next = List.head List.head = &newnode list.size++ return nil }
Prenode: = List.head preindex: = 0 For Preindex < i-2 { preindex++ Prenode = Prenode.next } //Perform insert Newnode.next = Prenode.next Prenode.next = &newnode list.size++ return nil }
//Delete the element at the specified position func (list *itemlinkedlist) RemoveAt(i int) (* Item, error) { List.lock.Lock () defer list.lock.Unlock ()
If i < 0 | | i > list.size { return nil, FMT. Errorf ("Index%d out of Bonuds", i) }
Curnode: = List.head preindex: = 0 For Preindex < i-1 { preindex++ Curnode = Curnode.next } Item: = Curnode.content Curnode.next = CurNode.next.next list.size-- return &item, nil }
//Gets the index of the specified element in the linked list func (list *itemlinkedlist) IndexOf(t Item) int { List.lock.RLock () defer list.lock.RUnlock () Curnode: = List.head locindex: = 0 For { if curnode.content = = t { return locindex } if curnode.next = = Nil { return -1 } Curnode = Curnode.next locindex++ } }
//Check if the linked list is empty func (list *itemlinkedlist) IsEmpty() bool { List.lock.RLock () defer list.lock.RUnlock () if list.head = = Nil { return true } return false }
//Get the length of the list func (list *itemlinkedlist) Size() int { List.lock.RLock () defer list.lock.RUnlock () Size: = 1 nextnode: = List.head For { if nextnode = = Nil | | nextnode.next = nil { //single-node linked list NextNode = nil Break } size++ NextNode = Nextnode.next } return size }
//Format print list func (list *itemlinkedlist) String() { List.lock.RLock () defer list.lock.RUnlock () Curnode: = List.head For { if curnode = = Nil { Break } Print(curnode.content) Print("") Curnode = Curnode.next } println() }
//Get the head node of the list func (list *itemlinkedlist) Head() *Node { List.lock.RLock () defer list.lock.RUnlock () return list.head }
|
Test Case: Linkedlist_test.go
Use
generate
Specify the element-specific data type for the linked list, such as:
1 2 |
//generate a ' Intlinkedlist ' linked list of ' int ' values genny-in linkedlist.go -out linkedlist_int.go gen " Item=int " |