循環鏈表實現原理及運用約瑟夫環實例

package main

import "fmt"

type LinkNode struct {
	Data interface{}
	Next *LinkNode
}

//建立循環鏈表
func (node *LinkNode) Create(Data ...interface{}) {
	if node == nil {
		return
	}
	if len(Data) == 0 {
		return
	}

	//記錄頭節點
	head := node

	for _, v := range Data {

		//建立一個新節點
		newNode := new(LinkNode)
		newNode.Data = v

		//當前節點的下一個節點爲新節點
		node.Next = newNode
		node = node.Next
	}
	//造成閉環
	//最後一個節點的下一個節點 爲第一個節點
	node.Next = head.Next
	node = head
}

//打印循環鏈表
func (node *LinkNode) Print() {
	if node == nil {
		return
	}

	//記錄循環鏈表的起始點
	start := node.Next

	//打印鏈表
	for {
		node = node.Next
		if node.Data != nil {
			fmt.Print(node.Data, " ")

		}
		if start == node.Next {
			break
		}

	}

	// 單向鏈表打印方式
	//for node.Next != nil {
	//	if node.Data != nil {
	//		fmt.Println(node.Data)
	//	}
	//	node = node.Next
	//}
}

//循環鏈表長度 返回值 個數
func (node *LinkNode) Length() int {
	if node == nil {
		return -1
	}

	//記錄循環鏈表的起始點
	start := node.Next

	//定義計數器
	i := 0
	for {
		node = node.Next
		i++
		if start == node.Next {
			break
		}
	}
	return i
}

//插入數據(下標 數據)
func (node *LinkNode) Insert(index int, Data interface{}) {
	if node == nil {
		return
	}
	//判斷位置是否越界
	if index < 0 || node.Length()+1 < index {
		return
	}
	if Data == nil {
		return
	}
	fmt.Println(node)
	//記錄鏈表第一個節點
	start := node.Next

	//記錄上一個節點
	preNode := node

	for i := 0; i < index; i++ {
		preNode = node
		node = node.Next
	}

	//建立新節點
	newNode := new(LinkNode)
	newNode.Data = Data
	//新節點的下一個節點爲node
	newNode.Next = node
	//上一個節點的下一個節點爲新節點
	preNode.Next = newNode

	//判斷若是是第一個節點須要將最後一個節點指向新節點
	if index == 1 {
		for {
			//判斷最後一個節點
			if start == node.Next {
				break
			}
			node = node.Next
		}
		//新節點爲最後一個節點的下一個節點
		node.Next = newNode
	}

}

//刪除數據 (下標)
func (node *LinkNode) Delete(index int) {
	if node == nil {
		return
	}
	if index < 0{
		return
	}

	//起始節點
	start := node.Next

	//記錄上一個節點
	preNode := node
	//循環找到刪除數據的位置
	for i := 0; i < index; i++ {
		preNode = node
		node = node.Next
	}


	//判斷若是刪除的是第一個節點
	if index == 1 {
		//temp記錄最後一個位置
		temp := start
		for {

			if start == temp.Next {
				break
			}

			temp = temp.Next
		}
		//將最後一個節點指向新節點
		temp.Next = node.Next
	}

	//刪除數據
	preNode.Next = node.Next

	//數據銷燬
	//node.Data = nil
	//node.Next = nil
	node = nil
}

 

//約瑟夫環//運用 -- 海盜分金
func main() {
	list := new(LinkNode)
	list.Create(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
		17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32)

	fmt.Println("原始數據:")
	list.Print()
	fmt.Println()
	fmt.Println("刪除數據:")
	i := 1
	for list.Length() > 2 {
		i += 3
		if i > list.Length() {
			i = list.Length()%3 + 1
		}
		list.Delete(i)
		list.Print()
		fmt.Println()
	}
}
相關文章
相關標籤/搜索