Go之数据结构

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
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值