1. 程式人生 > >go語言-常見資料結構與演算法

go語言-常見資料結構與演算法

選擇排序

//基礎版
func SelectionSort(arr []int, n int) {
	for i := 0; i < n; i ++ {
		minindex := i
		for j := i + 1; j < n; j++ {
			if arr[minindex] > arr[j] {
				minindex = j
			}
		}
		arr[minindex], arr[i] = arr[i], arr[minindex]
	}
}

//優化版本
func SelectionSortNew(arr []int, n int) {
	left := 0
	right := n - 1
	for left < right {
		minindex := left
		maxindex := right

		if arr[minindex] > arr[maxindex] {
			arr[minindex], arr[maxindex] = arr[maxindex], arr[minindex]
		}

		for i := left + 1; i < right; i++ {
			if arr[i] < arr[minindex] {
				minindex = i
			} else if arr[i] > arr[maxindex] {
				maxindex = i
			}
		}
		
		arr[minindex], arr[left] = arr[left], arr[minindex]
		arr[maxindex], arr[right] = arr[right], arr[maxindex]
		left++
		right++
	}
}

插入排序

//基礎版
func InserTionSort(arr []int, n int) {
	for i := 1; i < n; i++ {
		for j := i; j > 0; j-- {
			if arr[j-1] > arr[j] {
				arr[j-1], arr[j] = arr[j], arr[j-1]
			} else {
				break
			}
		}
	}
}

//優化版
func InserTionSortNew(arr []int, n int) {
	for i := 1; i < n; i ++ {
		var j int
		t := arr[i]
		for j = i; j > 0 && arr[j-1] > t; j-- {
			arr[j] = arr[j-1]
		}
		arr[j] = t
	}
}

氣泡排序

//基礎版
func BubbleSort(arr []int, n int) {
	for {
		newn := true
		for i := 1; i < n; i ++ {
			if arr[i] < arr[i-1] {
				arr[i], arr[i-1] = arr[i-1], arr[i]
				newn = false
			}
		}
		n--
		if newn {
			break
		}
	}
}

//優化版
func BubbleSortNew(arr []int, n int) {
	for {
		newn := 0
		for i := 1; i < n; i++ {
			if arr[i] < arr[i-1] {
				arr[i], arr[i-1] = arr[i-1], arr[i]
				newn = i
			}
		}
		n = newn
		if newn == 0 {
			break
		}
	}
}

自頂向下 歸併排序

//基礎版
func MergeSort(arr []int, n int) {
	mergesort(arr, 0, n-1)
}

func mergesort(arr []int, l, r int) {
	if l >= r {
		return
	}
	mid := (l + r) / 2
	mergesort(arr, l, mid)
	mergesort(arr, mid+1, r)
	merge(arr, l, mid, r)
}

func merge(arr []int, l, mid, r int) {
	aux := make([]int, r-l+1)
	for i := l; i <= r; i++ {
		aux[i-l] = arr[i]
	}
	i := l
	j := mid + 1
	for k := l; k <= r; k++ {
		if i > mid {
			arr[k] = aux[j-l]
			j++
		} else if j > r {
			arr[k] = aux[i-l]
			i++
		} else if aux[i-l] < aux[j-l] {
			arr[k] = aux[i-l]
			i++
		} else {
			arr[k] = aux[j-l]
			j++
		}
	}
}

//優化版
func MergeSort(arr []int, n int) {
	mergesort(arr, 0, n-1)
}

func mergesort(arr []int, l, r int) {
	//優化位置2.
	if r - l <= 15 {
		sort.InsertionsortMerge(arr,l,r)
		return
	}
	mid := (l + r) / 2
	mergesort(arr, l, mid)
	mergesort(arr, mid+1, r)
	//優化位置1.
	if arr[mid] > arr[mid+1] {
		merge(arr, l, mid, r)
	}
}

func merge(arr []int, l, mid, r int) {
	aux := make([]int, r-l+1)
	for i := l; i <= r; i++ {
		aux[i-l] = arr[i]
	}
	i := l
	j := mid + 1
	for k := l; k <= r; k++ {
		if i > mid {
			arr[k] = aux[j-l]
			j++
		} else if j > r {
			arr[k] = aux[i-l]
			i++
		} else if aux[i-l] < aux[j-l] {
			arr[k] = aux[i-l]
			i++
		} else {
			arr[k] = aux[j-l]
			j++
		}
	}
}
//歸併排序專用
func InsertionsortMerge(arr []int, l, r int) {
	for i := l+1; i <= r; i++ {
		t := arr[i]
		var j int
		for j = i; j > l && arr[j-1] > t; j-- {
			arr[j] = arr[j-1]
		}
		arr[j] = t
	}
}

自底向上 歸併排序

func MergeSortBU(arr []int, n int) {
	for sz := 1; sz < n; sz += sz {
		for i := sz; i < n-sz; i += sz + sz {
			merge(arr, i, i+sz-1, min(i+sz+sz-1, n-1))
		}
	}
}

func min(i, j int) int {
	if i > j {
		return j
	} else {
		return i
	}
}

快速排序

//基礎版
func quicksort(arr []int, n int) {
	quickSort(arr, 0, n-1)
}

func quickSort(arr []int, l, r int) {
	if l >= r {
		return
	}
	p := partition(arr, l, r)
	quickSort(arr, l, p-1)
	quickSort(arr, p+1, r)
}

func partition(arr []int, l, r int) int {
	v := arr[l]
	j := l
	for i := l + 1; i <= r; i++ {
		if arr[i] < v {
			arr[i], arr[j+1] = arr[j+1], arr[i]
			j++
		}
	}
	arr[l],arr[j] = arr[j],arr[l]
	return j
}

//優化版
func quicksort(arr []int, n int) {
	quickSort(arr, 0, n-1)
}

func quickSort(arr []int, l, r int) {
	if l >= r {
		return
	}
	p := partition(arr, l, r)
	quickSort(arr, l, p-1)
	quickSort(arr, p+1, r)
}

func partition(arr []int, l, r int) int {
	//優化位置
	t := rand.Intn(r)%(r-l+1) + l
	arr[l], arr[t] = arr[t], arr[l]
	v := arr[l]
	
	j := l
	for i := l + 1; i <= r; i++ {
		if arr[i] < v {
			arr[i], arr[j+1] = arr[j+1], arr[i]
			j++
		}
	}
	arr[l], arr[j] = arr[j], arr[l]
	return j
}

//雙路優化版
func quicksort2(arr []int, n int) {
	quickSort2(arr, 0, n-1)
}

func quickSort2(arr []int, l, r int) {
	if r-l <= 15 {
		sort.InsertionsortMerge(arr, l, r)
		return
	}

	p := partition2(arr, l, r)
	quickSort2(arr, l, p-1)
	quickSort2(arr, p+1, r)
}

func partition2(arr []int, l, r int) int {
	t := rand.Intn(r)%(r-l+1) + l
	arr[l], arr[t] = arr[t], arr[l]
	v := arr[l]

	i := l + 1
	j := r
	for {
		for i <= r && arr[i] < v {
			i++
		}
		for j >= l+1 && arr[j] > v {
			j--
		}
		if i > j {
			break
		}
		arr[i],arr[j] = arr[j],arr[i]
		i++
		j--
	}
	arr[l],arr[j] = arr[j],arr[l]
	return j
}

//三路優化版
func quickSort3ways(arr []int, n int) {
	quicksort3ways(arr, 0, n-1)
}

func quicksort3ways(arr []int, l, r int) {
	if r-l <= 15 {
		sort.InsertionsortMerge(arr, l, r)
		return
	}

	lt, gt := partition3ways(arr, l, r)
	quicksort3ways(arr, l, lt-1)
	quicksort3ways(arr, gt, r)
}

func partition3ways(arr []int, l, r int) (ltd, gtd int) {
	t := rand.Intn(r)%(r-l+1) + l
	arr[l], arr[t] = arr[t], arr[l]
	v := arr[l]

	lt := l
	gt := r + 1
	i := l+1
	for i < gt{
		if arr[i] < v{
			arr[i],arr[lt+1] = arr[lt+1],arr[i]
			i++
			lt++
		}else if arr[i] >v {
			arr[i],arr[gt-1] = arr[gt-1],arr[i]
			gt--
		}else{
			i++
		}
	}
	arr[l],arr[lt] = arr[lt],arr[l]
	return lt,gt
}

使用快速排序讀取指定陣列位置值

func FindArray(arr []int, n int) {
	findarray(arr, 0, n-1)
}

func findarray(arr []int, l, r int)int{
	if l >= r {
		return arr[l]
	}

	lt, gt := partitionfindarray(arr, l, r)
	if lt ==1000 {
		fmt.Println(arr[1000])
		return arr[1000]
	}else if 1000 < lt{
		return findarray(arr, l, lt-1)
	}else{
		return findarray(arr, gt, r)
	}
}

func partitionfindarray(arr []int, l, r int) (int, int) {
	t := rand.Intn(r)%(r-l+1) + l
	arr[l], arr[t] = arr[t], arr[l]
	v := arr[l]

	lt := l
	gt := r + 1
	i := l + 1
	for i < gt {
		if arr[i] < v {
			arr[i], arr[lt+1] = arr[lt+1], arr[i]
			i++
			lt++
		} else if arr[i] > v {
			arr[i], arr[gt-1] = arr[gt-1], arr[i]
			gt--
		} else {
			i++
		}
	}
	arr[l], arr[lt] = arr[lt], arr[l]
	return lt, gt
}

堆排序 使用最大堆排序

//最大堆
type MaxHeap struct {
	Data  []int
	count int
}

func (m *MaxHeap) MaxHeap(capacity int) {
	m.Data = make([]int, capacity)
	m.count = 0
}

func (m *MaxHeap) MaxHeap2(arr []int, n int){
	m.Data = make([]int, n+1)
	for i:=0;i<n;i++{
		m.Data = append(m.Data[:i+1],arr[i])
	}
	m.count = n
	count := m.count
	for k := count/2;k >= 1; k--{
		m.shiftDown(k)
	}
}

func (m *MaxHeap) Size() int {
	return m.count
}

func (m *MaxHeap) IsEmpty() bool {
	return m.count == 0
}

func (m *MaxHeap) Insert(data int) {
	m.Data = append(m.Data[:m.count+1],data)
	m.count++
	m.shiftUP()
}

func (m *MaxHeap) shiftUP() {
	d := m.count
	for d > 1 && m.Data[d] > m.Data[d/2] {
		m.Data[d], m.Data[d/2] = m.Data[d/2], m.Data[d]
		d = d/2
	}
}

func (m *MaxHeap)ExtractMax()int{
	if m.count <= 0{
		panic("index overflow")
	}

	t :=  m.Data[1]
	m.Data[1],m.Data[m.count] = m.Data[m.count],m.Data[1]
	m.count--
	m.shiftDown(1)

	return t
}

func (m *MaxHeap)shiftDown(k int){
	for k*2 <= m.count{
		j := k*2
		if j+1 <= m.count && m.Data[j+1] > m.Data[j]{
			j = j+1
		}
		if m.Data[k] > m.Data[j]{
			break
		}
		m.Data[k],m.Data[j] = m.Data[j],m.Data[k]
		k = j
	}
}

//堆排序1
func HeapSort(arr []int, n int){
	maxHeap := MaxHeap{}
	maxHeap.MaxHeap(n+1)
	for i := 0; i < n;i++{
		maxHeap.Insert(arr[i])
	}
	for i :=n-1;i >= 0 ; i--{
		arr = append(arr[:i],maxHeap.ExtractMax())
	}
}

/堆排序2
func HeapSort2(arr []int, n int){
	maxHeap := MaxHeap{}
	maxHeap.MaxHeap2(arr,n)
	for i :=n-1;i >= 0 ; i--{
		arr = append(arr[:i],maxHeap.ExtractMax())
	}
}

//堆排序3

func shiftDown(arr []int, n, i int){
	for i *2 +1 < n {
		j := i *2 +1
		if j+1 < n && arr[j+1] > arr[j]{
			j = j+1
		}

		if arr[i] > arr[j]{
			break
		}
		arr[i],arr[j] = arr[j],arr[i]
		i = j
	}
}

func HeapSort(arr []int, n int){
	for i:= (n-1)/2; i >= 0 ; i--{
		shiftDown(arr,n,i)
	}
	for i := n-1; i > 0 ; i--{
		arr[i],arr[0] = arr[0],arr[i]
		shiftDown(arr,i,0)
	}
}

單鏈表

type Node struct {
	data int
	Next *Node
}

type List struct {
	Head *Node
}

func (l *List) TailList(data int) {
	newp := new(Node)
	newp.data = data
	newp.Next = nil
	if l.Head == nil {
		l.Head = newp
		return
	}
	p := l.Head
	for p.Next != nil {
		p = p.Next
	}
	p.Next = newp
	return
}

func (l *List) HeadList(data int) {
	newp := new(Node)
	newp.data = data
	newp.Next = nil
	if l.Head == nil {
		l.Head = newp
		return
	}
	newp.Next = l.Head
	l.Head = newp
	return
}

func (l *List) delete(data int) {
	if l.Head == nil {
		return
	}
	p := l.Head
	if p.data == data {
		l.Head = p.Next
		return
	}
	p1 := p
	for p.Next != nil {
		if p.data == data {
			p1.Next = p.Next
			return
		}
		p1 = p
		p = p.Next
	}
	if p.data == data {
		p1.Next = nil
		return
	}
}
func main() {
	t := []int{1, 2, 3, 4, 5, 6, 7, 8}
	l := List{}
	for _, v := range t {
		l.TailList(v)
	}
	p := l.Head
	for p != nil {
		fmt.Printf("%d ", p.data)
		p = p.Next
	}
	l.delete(8)
	fmt.Println()
	p = l.Head
	for p != nil {
		fmt.Printf("%d ", p.data)
		p = p.Next
	}

}

雙向連結串列


type Node struct {
	data int
	Next *Node
	Prev *Node
}

type List struct {
	Head *Node
	Tail *Node
	Size int
}

func (l *List) TailAdd(data int) {
	newp := new(Node)
	newp.data = data
	if l.Tail != nil {
		newp.Prev = l.Tail
		l.Tail.Next = newp
	} else {
		l.Head = newp
	}
	l.Tail = newp
	l.Size ++
	return
}
func (l *List) HeadAdd(data int) {
	newp := new(Node)
	newp.data = data
	if l.Head != nil {
		newp.Next = l.Head
		l.Head.Prev = newp
	} else {
		l.Tail = newp
	}
	l.Head = newp
	l.Size++
	return

}

func (l *List) Remove(node *Node) bool {
	if node == nil {
		return false
	}
	prev := node.Prev
	next := node.Next
	if node == l.Head {
		l.Head = next
	} else {
		prev.Next = next
	}
	if node == l.Tail {
		l.Tail = prev
	} else {
		next.Prev = prev
	}
	l.Size --
	return true
}

func (l *List) SizeList() int {
	return l.Size
}