Go编写的Linktable库

Godyc 2022-06-30 11:08:55

## 一、LinkTable类(接口类)的定义

首先定义LinkTable的节点类和链表类

// LinkTable节点类定义
type LinkTableNode struct {
	next *LinkTableNode
	data int
}

// LinkTable链表类定义
type LinkTable struct {
	pHead     *LinkTableNode
	pTail     *LinkTableNode
	SumOfNode int
	// mutex_t   Mutex
}

接着定义操作LinkTable节点的一系列方法:

  1. 创建节点
    func CreateLinkTable() *LinkTable {
    	var pLinkTable LinkTable
    	pLinkTable.pHead = nil
    	pLinkTable.pTail = nil
    	pLinkTable.SumOfNode = 0
    	return &pLinkTable
    }
    
  2. 添加链表节点

    // 添加链表节点,创建成功返回1,否则返回0
    func AddLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int {
    	if pLinkTable == nil || pNode == nil {
    		return 0
    	}
    	pNode.next = nil
    	if pLinkTable.pHead == nil {
    		pLinkTable.pHead = pNode
    	}
    	if pLinkTable.pTail == nil {
    		pLinkTable.pTail = pNode
    	} else {
    		pLinkTable.pTail.next = pNode
    		pLinkTable.pTail = pNode
    	}
    	pLinkTable.SumOfNode++
    	return 1
    }
  3. 删除列表节点

    // 删除链表节点,删除成功返回1,否则返回0
    func DelLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) int {
    	if pLinkTable == nil || pNode == nil {
    		return 0
    	}
    	if pLinkTable.pHead == pNode {
    		pLinkTable.pHead = pLinkTable.pHead.next
    		pLinkTable.SumOfNode--
    		if pLinkTable.SumOfNode == 0 {
    			pLinkTable.pTail = nil
    		}
    		return 1
    	}
    	for pTempNode := pLinkTable.pHead; pTempNode != nil; pTempNode = pTempNode.next {
    		if pTempNode.next == pNode {
    			pTempNode.next = pTempNode.next.next
    			pLinkTable.SumOfNode--
    			if pLinkTable.SumOfNode == 0 {
    				pLinkTable.pTail = nil
    			}
    			return 1
    		}
    	}
    	return 0
    }
  4. 获取链表首节点

    // 获取链表首节点
    // ps.此方法似乎有些多余,直接调用 pLinkTable.head 就可得到结果
    func GetLinkTableHead(pLinkTable *LinkTable) *LinkTableNode {
    	// TODO: 这里如果 pLinkTable指针为空或者pLinkTable节点为空都是返回nil,应当抛出一个异常
    	if pLinkTable == nil {
    		return nil
    	}
    	return pLinkTable.pHead
    }
  5. 获取下一个链表节点

    // 获取下一个链表节点
    // ps.此方法似乎有些多余,直接调用 pNode.next 就可完成函数操作
    func GetNextLinkTableNode(pLinkTable *LinkTable, pNode *LinkTableNode) *LinkTableNode {
    	if pLinkTable == nil || pNode == nil {
    		return nil
    	}
    	for pTempNode := pLinkTable.pHead; pTempNode != nil; pTempNode = pTempNode.next {
    		if pTempNode == pNode {
    			return pTempNode.next
    		}
    	}
    	return nil
    }

## 二、menu程序库的定义

参照《高级软件工程》课程中的C++代码,这里实现了help、version、quit三种指令的方法并且进行了测试。

  1. 类、接口的定义和接口的实现
    // 定义操作符节点类(继承自LinkTable)
    type CmdNode struct {
    	*LinkTableNode
    }
    
    // 定义数字节点类(继承自Linktable)
    type NumNode struct {
    	*LinkTableNode
    }
    
    // 操作符对照表
    var cmds = [3]string{"help", "version", "quit"}
    
    // 定义接口
    type FindCmder interface {
    	FindCmd()
    }
    
    // 操作符节点类的接口实现
    func (a *CmdNode) FindCmd() string {
    	return cmds[a.data]
    }
    
    // 数字类的接口实现
    func (a *NumNode) FindCmd() int {
    	return a.data
    }
  2. 功能测试(主函数)
    func test() {
    	pLinkTable := CreateLinkTable()
    	var dataNums = [3]int{2, 0, 1}
    	// 添加节点
    	for i := 0; i < len(dataNums); i++ {
    		pNode := &LinkTableNode{nil, dataNums[i]}
    		if AddLinkTableNode(pLinkTable, pNode) == 0 {
    			fmt.Println("Add Node Failed!")
    			break
    		}
    	}
    	// 测试接口的实现
    	fmt.Println("==========测试CmdNode类的接口实现==========")
    	for pTempNode := pLinkTable.pHead; pTempNode != nil; pTempNode = pTempNode.next {
    		d := CmdNode{pTempNode}
    		fmt.Print(d.FindCmd() + " ")
    	}
    	fmt.Println()
    	fmt.Println("==========测试NumNode类的接口实现==========")
    	for pTempNode := pLinkTable.pHead; pTempNode != nil; pTempNode = pTempNode.next {
    		d := NumNode{pTempNode}
    		fmt.Print(d.FindCmd())
    		fmt.Print(" ")
    	}
    	fmt.Println()
    	// 测试删除节点
    	fmt.Println("==========测试删除节点==========")
    	pHeadNode := GetLinkTableHead(pLinkTable)
    	DelLinkTableNode(pLinkTable, pHeadNode)
    	for pTempNode := pLinkTable.pHead; pTempNode != nil; pTempNode = pTempNode.next {
    		d := NumNode{pTempNode}
    		fmt.Print(d.FindCmd())
    		fmt.Print(" ")
    	}
    	fmt.Println()
    }

## 三、心得体会

经过本次实验,加深了对软件工程中“接口”概念的理解。在理解课堂上讲述的概念的前提下,具体实验的过程中遇到了一些编写以及调试的问题,这无疑归因于对Golang语言掌握程度的不足。学习《高级软件工程》课程,不仅要学习理论知识,更要动手实践,才能真正掌握课堂上的内容。

版本库连接:https://github.com/TJUxyc/ASE-HW6

作者:494

...全文
94 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧