1. 字典树
package structure
// 字典表,适用于自动补全
const Size = 26
type trieNode struct {
childrens [26]*trieNode
Is bool
}
type trieTree struct {
root *trieNode
}
func (t *trieTree) Insert(word string) {
currentNode := t.root
for i := 0; i < len(word); i++ {
index := word[i] - 'a'
if currentNode.childrens[index] == nil {
currentNode.childrens[index] = &trieNode{}
}
currentNode = currentNode.childrens[index]
}
currentNode.Is = true
}
func (t *trieTree) find(word string) bool {
currentNode := t.root
for i := 0; i < len(word); i++ {
index := word[i] - 'a'
if currentNode.childrens[index] == nil {
return false
}
currentNode = currentNode.childrens[index]
}
if currentNode.Is {
return true
}
return false
}
2. 二叉查找树
package structure
import "fmt"
// 二叉查找树
type bstnode struct {
value int
left *bstnode
right *bstnode
}
type Root struct {
root *bstnode
}
func main() {
bst := &Root{}
array := []int{2,3,5,2,0}
for _,value := range array{
bst.Insert(value)
}
bst.Find(2)
}
func (r *Root) reset() {
r.root = nil
}
func (r *Root) Insert(data int) {
r.insertRec(r.root, data)
}
func (r *Root) insertRec(node *bstnode, data int) *bstnode {
if r.root == nil {
r.root = &bstnode{
value: data,
}
return r.root
}
// 递归寻找左右空节点的终止条件
if node == nil {
return &bstnode{
value: data,
}
}
if data < node.value {
node.left = r.insertRec(node.left, data)
}
if data > node.value {
node.right = r.insertRec(node.right, data)
}
return node
}
func (r *Root) Find(data int) error {
node := r.findRec(r.root, data)
if node == nil {
return fmt.Errorf("没有找到该节点")
}
fmt.Println("該节点已存在")
return nil
}
func (r *Root) findRec(node *bstnode, data int) *bstnode {
if r.root.value == data {
return r.root
}
// 递归寻找左右空节点的终止条件
if node == nil {
return nil
}
if data < node.value {
return r.findRec(node.left, data)
} else {
return r.findRec(node.right, data)
}
}
3. 散列表
package structure
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"encoding/binary"
)
// 桶
type Bucket struct {
Key string
Data int
}
// 无链表的散列表,哈希碰撞时,就向上索引
type HashTable struct {
Buckets []Bucket
Capacity int32
used int32
}
func (h *HashTable) Set(key string, value int) {
bucket := Bucket{key, value}
hashCode := GetHashCode(key, 1)
index := hashCode % (h.Capacity - 1)
h.AddBucket(index, key, bucket)
}
func (h *HashTable) AddBucket(index int32, key string, bucket Bucket) {
empty := Bucket{}
if h.Capacity == h.used {
panic("Table is full")
}
if Ok := h.Buckets[index]; Ok != empty {
if Ok.Key == key {
h.Buckets[index] = bucket
return
}
index++
for {
if index >= h.Capacity{
index = 0
}
if Ok := h.Buckets[index]; Ok != empty {
if Ok.Key == key {
h.Buckets[index] = bucket
return
}
index++
}else {
h.Buckets[index] = bucket
h.used++
return
}
}
} else {
h.Buckets[index] = bucket
h.used++
}
}
func (h *HashTable) FindBucket(index int32, key string) Bucket {
empty := Bucket{}
if Ok := h.Buckets[index]; Ok != empty {
if Ok.Key == key {
return h.Buckets[index]
}
index++
for {
if index >= h.Capacity{
index = 0
}
if Ok := h.Buckets[index]; Ok != empty {
if Ok.Key == key {
return h.Buckets[index]
}
index++
}else {
return empty
}
}
}
return empty
}
func GetHashCode(key string, hashType int) int32 {
var result []byte
switch hashType {
case 1:
Md5 := md5.New()
Md5.Write([]byte(key))
result = Md5.Sum([]byte(""))
case 2:
Sha := sha1.New()
Sha.Write([]byte(key))
result = Sha.Sum([]byte(""))
}
buffer := bytes.NewBuffer(result)
var x int32
binary.Read(buffer, binary.BigEndian, &x)
return x
}
4. 栈
package structure
import (
"container/list"
"fmt"
)
type CustStack struct {
Stack *list.List
}
func main() {
stack := &CustStack{
list.New(),
}
stack.Push("hello")
stack.Push("world")
for stack.Size()>0 {
front, _ := stack.Front()
fmt.Println("value:",front)
stack.Pop()
}
}
func (s *CustStack) Push(value string) {
s.Stack.PushFront(value)
}
func (s *CustStack) Pop() error {
if s.Stack.Len() > 0 {
element := s.Stack.Front()
s.Stack.Remove(element)
}
return fmt.Errorf("Stack is empty")
}
func (s *CustStack) Front() (string, error) {
if s.Stack.Len() > 0 {
if value, OK := s.Stack.Front().Value.(string); OK {
return value, nil
}
return "", fmt.Errorf("Stack is empty")
}
return "", fmt.Errorf("Stack is empty")
}
func (s *CustStack)Size() int {
return s.Stack.Len()
}
func (s *CustStack)Empty()bool{
return s.Stack.Len() == 0
}
5. 队列
package structure
import (
"container/list"
"fmt"
)
type Queue struct {
Queue *list.List
}
func main() {
nowqueue := &Queue{
list.New(),
}
nowqueue.Enqueue("hello\n")
nowqueue.Enqueue("World\n")
for nowqueue.Size()>0 {
front, _ := nowqueue.Front()
fmt.Println("Front value:",front)
nowqueue.Dequeue()
}
}
func (q *Queue) Enqueue(value string) {
q.Queue.PushBack(value)
}
func (q *Queue) Dequeue() error {
if q.Queue.Len() >0 {
front := q.Queue.Front()
q.Queue.Remove(front)
}
return fmt.Errorf("Queue is Empty")
}
func (q *Queue) Front()(string,error){
if q.Queue.Len()>0{
if value,Ok := q.Queue.Front().Value.(string);Ok{
return value,nil
}
return "",fmt.Errorf("类型不匹配")
}
return "",fmt.Errorf("queue is empty")
}
func (q *Queue) Size() int {
return q.Queue.Len()
}
func (q *Queue) Empty() bool {
return q.Queue.Len() == 0
}
6. 双向链表
package structure
import "fmt"
type Node struct {
Data int
NextNode *Node
PreNode *Node
}
type LinkedList struct {
head *Node
tail *Node
size int
}
func initDoublyList() *LinkedList {
return &LinkedList{}
}
func (link *LinkedList) Size() int {
return link.size
}
func CreateLinkedList() {
data := []int{1, 22, 23, 2, 33}
link := LinkedList{}
for i := 0; i < len(data); i++ {
insertNode(&link, data[i])
}
_ = link.TraverseNode()
}
func insertNode(link *LinkedList, num int) {
node := &Node{Data: num}
if link.head == nil {
link.head = node
link.tail = node
} else {
link.tail.NextNode = node
node.PreNode = link.tail
link.tail = node
}
link.size++
return
}
func (link *LinkedList) TraverseNode() error {
currentNode := link.head
if currentNode == nil {
return fmt.Errorf("doubleList is empty")
}
for currentNode != nil {
fmt.Printf("value:%v,prv:%v,next:%v\n", currentNode.Data, currentNode.PreNode, currentNode.NextNode)
currentNode = currentNode.NextNode
}
fmt.Println("向后遍历结束")
return nil
}