go語言-常見資料結構與演算法
阿新 • • 發佈:2018-11-09
選擇排序
//基礎版 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
}