zoukankan      html  css  js  c++  java
  • 循环链表实现原理及运用约瑟夫环实例

    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() } }
  • 相关阅读:
    showModalDialog和showModelessDialog使用心得
    C# 实现验证文本框中输入的是数值型??
    将Asp.Net页面输出到EXCEL里去
    timespan 和 datetime 的比较
    使用 Reporting Services 中的窗体身份验证
    DataGrid使用技巧················CSDN 收藏地址。。
    公司如何让留住技术人员??
    如何用多线程来实现ping多台机器??
    Datagrid根据选择的checkbox编辑和更新多行记录····
    做技术,切不可沉湎于技术 !
  • 原文地址:https://www.cnblogs.com/lurenq/p/12081818.html
Copyright © 2011-2022 走看看