go语言中container容器数据结构heap、list、ring

heap堆的使用:

package main

import (
	"container/heap"
	"fmt"
)

type IntHeap []int

//我们自定义一个堆需要实现5个接口
//Len(),Less(),Swap()这是继承自sort.Interface
//Push()和Pop()是堆自已的接口

//返回长度
func (h *IntHeap) Len() int {
	return len(*h);
}

//比较大小(实现最小堆)
func (h *IntHeap) Less(i, j int) bool {
	return (*h)[i] < (*h)[j];
}

//交换值
func (h *IntHeap) Swap(i, j int) {
	(*h)[i], (*h)[j] = (*h)[j], (*h)[i];
}

//压入数据
func (h *IntHeap) Push(x interface{}) {
	//将数据追加到h中
	*h = append(*h, x.(int))
}

//弹出数据
func (h *IntHeap) Pop() interface{} {
	old := *h;
	n := len(old);
	x := old[n-1];
	//让h指向新的slice
	*h = old[0: n-1];
	//返回最后一个元素
	return x;
}

//打印堆
func (h *IntHeap) PrintHeap() {
	//元素的索引号
	i := 0
	//层级的元素个数
	levelCount := 1
	for i+1 <= h.Len() {
		fmt.Println((*h)[i: i+levelCount])
		i += levelCount
		if (i + levelCount*2) <= h.Len() {
			levelCount *= 2
		} else {
			levelCount = h.Len() - i
		}
	}
}

func main() {
	a := IntHeap{6, 2, 3, 1, 5, 4};
	//初始化堆
	heap.Init(&a);
	a.PrintHeap();
	//弹出数据,保证每次操作都是规范的堆结构
	fmt.Println(heap.Pop(&a));
	a.PrintHeap();
	fmt.Println(heap.Pop(&a));
	a.PrintHeap();
	heap.Push(&a, 0);
	heap.Push(&a, 8);
	a.PrintHeap();
}

list链表的使用:

package main;

import (
	"container/list"
	"fmt"
)

func printList(l *list.List) {
	for e := l.Front(); e != nil; e = e.Next() {
		fmt.Print(e.Value, " ");
	}
	fmt.Println();
}

func main() {
	//创建一个链表
	l := list.New();

	//链表最后插入元素
	a1 := l.PushBack(1);
	b2 := l.PushBack(2);

	//链表头部插入元素
	l.PushFront(3);
	l.PushFront(4);

	printList(l);

	//取第一个元素
	f := l.Front();
	fmt.Println(f.Value);

	//取最后一个元素
	b := l.Back();
	fmt.Println(b.Value);

	//获取链表长度
	fmt.Println(l.Len());

	//在某元素之后插入
	l.InsertAfter(66, a1);

	//在某元素之前插入
	l.InsertBefore(88, a1);

	printList(l);

	l2 := list.New();
	l2.PushBack(11);
	l2.PushBack(22);
	//链表最后插入新链表
	l.PushBackList(l2);
	printList(l);

	//链表头部插入新链表
	l.PushFrontList(l2);
	printList(l);

	//移动元素到最后
	l.MoveToBack(a1);
	printList(l);

	//移动元素到头部
	l.MoveToFront(a1);
	printList(l);

	//移动元素在某元素之后
	l.MoveAfter(b2, a1);
	printList(l);

	//移动元素在某元素之前
	l.MoveBefore(b2, a1);
	printList(l);

	//删除某元素
	l.Remove(a1);
	printList(l);
}

ring环的使用:

package main;

import (
	"container/ring"
	"fmt"
)

func printRing(r *ring.Ring) {
	r.Do(func(v interface{}) {
		fmt.Print(v.(int), " ");
	});
	fmt.Println();
}

func main() {
	//创建环形链表
	r := ring.New(5);
	//循环赋值
	for i := 0; i < 5; i++ {
		r.Value = i;
		//取得下一个元素
		r = r.Next();
	}
	printRing(r);
	//环的长度
	fmt.Println(r.Len());

	//移动环的指针
	r.Move(2);

	//从当前指针删除n个元素
	r.Unlink(2);
	printRing(r);

	//连接两个环
	r2 := ring.New(3);
	for i := 0; i < 3; i++ {
		r2.Value = i + 10;
		//取得下一个元素
		r2 = r2.Next();
	}
	printRing(r2);

	r.Link(r2);
	printRing(r);
}

  

时间: 2024-10-12 12:13:20

go语言中container容器数据结构heap、list、ring的相关文章

对C语言中static的理解

对C语言中的static关键字的深入理解 在一次面试的时候面试官问我static全局变量与全局变量的区别,之前虽然用过但是并没仔细去搞懂他,这次来细心的学习一下. 基本概念 使用static有三种情况: 函数内部static变量 函数外部static变量 static函数 函数内部的static变量,关键在于生命周期持久,他的值不会随着函数调用的结束而消失,下一次调用时,static变量的值,还保留着上次调用后的内容. 函数外部的static变量,以及static函数,关键在于私有性,它们只属于

javascript中模拟实现java语言中的map

//javascript中模拟实现java语言中的map 实现代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script type="text/javascript"> //private var obj={};//空的对象容器,用于承装键值对 function Map() { //put方法 th

java 程序语言中的LinkedList 集合基本方法演示

java 程序语言中的LinkedList 集合基本方法演示 import java.util.Iterator; import java.util.LinkedList; public class LinkedListDemos { public static void main(String[] args) { // 新建一个容器 LinkedList link = new LinkedList(); link.addFirst("abc1"); link.addFirst(&qu

Java语言中Object对象的hashCode()取值的底层算法是怎样实现的?

Java语言中,Object对象有个特殊的方法:hashcode(), hashcode()表示的是JVM虚拟机为这个Object对象分配的一个int类型的数值,JVM会使用对象的hashcode值来提高对HashMap.Hashtable哈希表存取对象的使用效率. 关于Object对象的hashCode()返回值,网上对它就是一个简单的描述:"JVM根据某种策略生成的",那么这种策略到底是什么呢?我有一个毛病,遇到这种含糊其辞的东西,就想探个究竟,所以,本文就将hashCode()本

C语言中setjmp与longjmp学习笔记

一.基础介绍 ?? ?头文件:#include<setjmp.h> ?? ?原型:??int?setjmp(jmp_buf envbuf) ?? ?宏函数setjmp()在缓冲区envbuf中保存系统堆栈里的内容,供longjmp()以后使用.首次调用setjmp()宏时,返回值为0,然而longjmp()把一个变原传递给setjmp(),该值(恒不为0)就是调用longjmp()后出现的setjmp()的值. void longjmp(jmp_buf envbuf,int status);

Go语言中的map(十一)

map是一种无序的基于 key-value 的数据结构,Go语言中的map是引用类型,所以跟切片一样需要初始化才能使用. 定义map 定义 map 的语法如下: map[keyType]ValueType // keyType 键的类型 // ValueType 键对应的值的类型 定义 map 而不初始化时,默认值等于 nil,此时不能直接赋值的,如: func main() { var a map[string]int // 定义了map fmt.Println(a==nil) // true

c语言中的malloc函数

少壮不努力,大一的时候c语言学得不扎实,最近学数据结构的时候看到c语言中malloc函数都不知道了,这里记录一下,避免以后再忘. malloc的全称是memory allocation,中文叫动态内存分配,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存,且分配的大小就是程序要求的大小. 函数:void *malloc(int size); malloc 向系统申请分配指定size个字节的

在Swift语言中,关于Any,AnyObject,AnyClass的区别与联系

在Swift语言中,协议定义类或结构体应该遵守的变量和方法集合,如下所示,这个一个标准的协议的声明: protocol NSObjectProtocol { func isEqual(object: AnyObject?) -> Bool var hash: Int { get } var superclass: AnyClass? { get } func `self`() -> Self! func isProxy() -> Bool func isKindOfClass(aClas

GO语言中import的规则和用法

GO语言中引入包使用import,我将在本文讲解下规则和用法. 一些规则: 1.包中不能有main方法. 2.同文件夹中可以直接用方法名调用. 3.main函数建议放在package main里4.main不能调用同个目录下的其它文件中的方法. 5.还可以把包放在上级的目录中,如: /src/myFolder/foo/bar1.go #package foo /src/myFolder/foo/bar2.go #package foo /src/myFolder/foo/bar3.go #pac