主程式 CH3-5-LinkedList.vb :
Imports System.IO Module Module_CH3_5_LinkedList Private myListLib As ClassLinkedList = New ClassLinkedList Private myLinkedList As ClassLinkedList.ListNode Private Function GetNodePositionByData(ByVal NodeData As Integer) As Integer Dim NodePointer As ClassLinkedList.ListNode Dim Counter As Integer Counter = 1 NodePointer = Module_CH3_5_LinkedList.myLinkedList Do While Not NodePointer Is Nothing AndAlso NodePointer.NodeData <> NodeData '0 = NULL Counter += 1 NodePointer = NodePointer.NextNode Loop If NodePointer Is Nothing Then Counter = -1 End If Return Counter End Function Private Function GetNodeByPosition(ByVal NodePosition As Integer) As ClassLinkedList.ListNode Dim NodePointer As ClassLinkedList.ListNode Dim Counter As Integer Counter = 1 NodePointer = Module_CH3_5_LinkedList.myLinkedList Do While Not NodePointer Is Nothing AndAlso Counter <> NodePosition '0 = NULL Counter += 1 NodePointer = NodePointer.NextNode Loop If NodePointer Is Nothing Then Counter = -1 End If Return NodePointer End Function Private Function SwapNodes(ByVal NodePos() As Integer) As Boolean Dim NodePointer() As ClassLinkedList.ListNode = {Nothing, Nothing} Dim Counter, NodeData As Integer Dim OK As Boolean = False Counter = 1 NodePointer(0) = Module_CH3_5_LinkedList.myLinkedList Do While Not NodePointer(0) Is Nothing AndAlso Counter <> NodePos(0) '0 = NULL Counter += 1 NodePointer(0) = NodePointer(0).NextNode Loop If NodePointer(0) Is Nothing Then Else Counter = 1 NodePointer(1) = Module_CH3_5_LinkedList.myLinkedList Do While Not NodePointer(1) Is Nothing AndAlso Counter <> NodePos(1) '0 = NULL Counter += 1 NodePointer(1) = NodePointer(1).NextNode Loop If (NodePointer(1) Is Nothing) Then Else NodeData = NodePointer(0).NodeData NodePointer(0).NodeData = NodePointer(1).NodeData NodePointer(1).NodeData = NodeData OK = True End If End If Return OK End Function Public Sub Main() Dim KbdChoice, Counter, NodePos(1) As Integer Dim NodePointer As ClassLinkedList.ListNode Dim DataArray() As String Dim myDataFileReader As StreamReader = Nothing Dim ConsoleInput As String = Nothing Try myDataFileReader = File.OpenText("List.in") ConsoleInput = myDataFileReader.ReadLine() myDataFileReader.Close() Catch ex As Exception Console.Write(ex.Message) Exit Sub End Try DataArray = ConsoleInput.Split(" ") Module_CH3_5_LinkedList.myLinkedList = myListLib.GetNode() Module_CH3_5_LinkedList.myLinkedList.NodeData = Val(DataArray(0)) Module_CH3_5_LinkedList.myLinkedList.NextNode = Nothing For k As Integer = 1 To DataArray.Length - 1 Module_CH3_5_LinkedList.myListLib.InsertTail(Module_CH3_5_LinkedList.myLinkedList, Val(DataArray(k))) Next Do While True Console.Write("串列內容 => ") Module_CH3_5_LinkedList.myListLib.PrintList(Module_CH3_5_LinkedList.myLinkedList) Console.WriteLine("(1) 附加節點") Console.WriteLine("(2) 插入節點") Console.WriteLine("(3) 刪除節點") Console.WriteLine("(4) 依照節點位置查詢資料") Console.WriteLine("(5) 依照資料查詢節點位置") Console.WriteLine("(6) 依照節點位置對調資料") Console.WriteLine("(0) 結束") Console.Write("請輸入選項 => ") Try KbdChoice = Console.ReadLine() Catch ex As Exception KbdChoice = 8 ' 總選項數 + 1 End Try Select Case KbdChoice Case 0 Exit Sub Case 1 Console.Write("請輸入欲附加之資料 => ") Try ConsoleInput = Console.ReadLine() Catch ex As Exception Console.WriteLine("輸入型態錯誤! 請輸入整數值") Continue Do Finally End Try Module_CH3_5_LinkedList.myListLib.InsertTail(Module_CH3_5_LinkedList.myLinkedList, ConsoleInput) Case 2 Console.Write("請輸入欲插入之資料 => ") Try ConsoleInput = Console.ReadLine() Catch ex As Exception Console.WriteLine("輸入型態錯誤! 請輸入整數值") Continue Do End Try Console.Write("請輸入欲插入之位置 => ") NodePos(0) = Console.ReadLine() If NodePos(0) = 1 Then NodePointer = Module_CH3_5_LinkedList.myListLib.GetNode() NodePointer.NodeData = Val(ConsoleInput) NodePointer.NextNode = Module_CH3_5_LinkedList.myLinkedList Module_CH3_5_LinkedList.myLinkedList = NodePointer Else Counter = 1 NodePointer = Module_CH3_5_LinkedList.myLinkedList Do While (Counter <> (NodePos(0) - 1) AndAlso Not NodePointer Is Nothing) Counter += 1 NodePointer = NodePointer.NextNode Loop If NodePointer Is Nothing Then Console.WriteLine("插入失敗") ElseIf Module_CH3_5_LinkedList.myListLib.InsertAfter(NodePointer, Val(ConsoleInput)) = 0 Then Console.WriteLine("插入失敗") End If End If Case 3 Console.Write("請輸入欲刪除之資料 => ") NodePos(0) = Val(Console.ReadLine()) Counter = 1 NodePointer = Module_CH3_5_LinkedList.myLinkedList Do While Not NodePointer Is Nothing AndAlso NodePointer.NodeData <> NodePos(0) '0 = NULL Counter += 1 NodePointer = NodePointer.NextNode Loop If NodePointer Is Nothing Then Console.WriteLine("此資料不在串列中") ElseIf Counter = 1 Then Module_CH3_5_LinkedList.myLinkedList = Module_CH3_5_LinkedList.myLinkedList.NextNode ElseIf Module_CH3_5_LinkedList.myListLib.DeleteNode(myLinkedList, NodePointer) = 0 Then Console.WriteLine("刪除失敗") End If Case 4 Console.Write("請輸入欲查詢之位置 => ") NodePos(0) = Val(Console.ReadLine()) NodePointer = Module_CH3_5_LinkedList.GetNodeByPosition(NodePos(0)) If NodePointer Is Nothing Then Console.WriteLine("資料位置={0} 不在串列中", NodePos) Else Console.WriteLine("資料={0}", NodePointer.NodeData) End If Case 5 Console.Write("請輸入欲查詢之資料 => ") Try ConsoleInput = Console.ReadLine() Catch ex As Exception Console.WriteLine("輸入型態錯誤! 請輸入整數值") Continue Do End Try NodePos(0) = Module_CH3_5_LinkedList.GetNodePositionByData(Val(ConsoleInput)) If NodePos(0) = -1 Then Console.WriteLine("資料={0} 不在串列中", ConsoleInput) Else Console.WriteLine("節點位置={0}", NodePos) End If Case 6 Console.Write("請輸入調換位置 (兩組數字) => ") DataArray = Console.ReadLine().Split(" ") NodePos(0) = Val(DataArray(0)) NodePos(1) = Val(DataArray(1)) If Module_CH3_5_LinkedList.SwapNodes(NodePos) Then Else Console.WriteLine("節點位置錯誤") End If Case Else Console.WriteLine("選項錯誤") End Select Loop End Sub End Module
程式庫 ClassLinkedList.vb :
Public Class ClassLinkedList Public Class ListNode '3.5.1 宣告節點類型 Public NodeData As Integer Public NextNode As ListNode End Class '3.5.4 插入新節點 Public Function InsertAfter(ByRef NodePointer As ListNode, ByVal NodeValue As Integer) 'NodePointer是欲插入節點的前一點 Dim NewNode As ListNode NewNode = GetNode() '動態配置節點 If NewNode Is Nothing Then '配置失敗 Return 0 End If NewNode.NodeData = NodeValue '將新節點的值填入 NewNode.NextNode = NodePointer.NextNode '掛上新節點的鏈結 NodePointer.NextNode = NewNode '改變原有節點的鏈結 Return 1 End Function Public Function InsertTail(ByVal NodePointer As ListNode, ByVal NodeValue As Integer) As Integer 'NodePointer是根節點 Dim NewNode As ListNode = GetNode() If NewNode Is Nothing Then Console.Write("沒有空的節點") '記憶體配置失敗 Return 0 End If NewNode.NodeData = NodeValue '將新的資料值填入新節點 NewNode.NextNode = Nothing Do While Not NodePointer.NextNode Is Nothing '迴圈結束後NodePointer會指向最後一個節點 NodePointer = NodePointer.NextNode Loop NodePointer.NextNode = NewNode End Function '3.5.5 刪除原有節點 Public Function DeleteNode(ByVal ListA As ListNode, ByVal OldNode As ListNode) As Integer ' ListA head開頭, CurrentNode指標節點 Dim PreviousNode As ListNode PreviousNode = GetPreNode(ListA, OldNode) '必須找出前一個節點的指標, 將移除的指標指給前一個節點 If PreviousNode Is Nothing Then 'Old節點不在串列中 Return 0 '無法刪除,傳回失敗訊息 End If PreviousNode.NextNode = OldNode.NextNode '越過刪除原有節點 FreeNode(OldNode) Return 1 End Function '3.5.6 建立鏈結串列 Public Function GetPreNode(ByVal ListA As ListNode, ByVal CurrentNode As ListNode) As ListNode '前一個節點的指標 Dim NodePointer, NodePointer2 As ListNode NodePointer = ListA NodePointer2 = ListA.NextNode Do While Not NodePointer2 Is Nothing AndAlso NodePointer2.NodeData <> CurrentNode.NodeData NodePointer = NodePointer2 NodePointer2 = NodePointer2.NextNode 'NodePointer和NodePointer2各往右一步 Loop If Not NodePointer2 Is Nothing Then '成功找到 Return NodePointer Else Return Nothing '沒有找到 End If End Function Public Sub PrintList(ByVal NodePointer As ListNode) '第一個節點的位址資料指向第一筆資枓 Do While Not NodePointer Is Nothing ' NULL Console.Write(NodePointer.NodeData & " ") NodePointer = NodePointer.NextNode Loop Console.WriteLine() End Sub Public Function GetSumOfList(ByVal NodePointer As ListNode) As Integer '第一個節點的位址資料指向第一筆資枓 Dim Ret As Integer = 0 Do While Not NodePointer Is Nothing ' NULL Ret = Ret + Integer.Parse(NodePointer.NodeData) NodePointer = NodePointer.NextNode Loop Return Ret End Function Public Function GetAverageOfList(ByVal NodePointer As ListNode) As Integer '第一個節點的位址資料指向第一筆資枓 Dim Ret As Integer = 0 Dim Counter As Integer = 0 Do While Not NodePointer Is Nothing ' NULL Ret = Ret + Integer.Parse(NodePointer.NodeData) Counter = Counter + 1 NodePointer = NodePointer.NextNode Loop Return (Ret / Counter) End Function Public Sub FreeAllNode(ByRef ListA As ListNode) '從第一個節點往後刪節點 Dim NodePointer As ListNode Do While Not ListA Is Nothing NodePointer = ListA.NextNode FreeNode(ListA) ListA = NodePointer Loop End Sub Public Sub FreeNode(ByRef NodePointer As ListNode) NodePointer = Nothing End Sub Public Function GetNode() As ListNode Dim CurrentNode As New ListNode Return CurrentNode End Function End Class