[数据结构]freebasic实现动态单链表

前言

首先,感谢勇芳为我们提供了强大的编辑器vfb。这是我在csdn上第一次发关于freebasic的博客。因为我是一名初三学生,没有时间系统学习fb,以下代码有不规范的还请各位大佬指出[真诚]
(转载请标明出处)

百度百科对链表的定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

单链表的模型

单链表模型如下图所示[图片来自网络]
单链表

实现思路

freebasic支持指针,但又不像C++支持new关键字,刚开始,我想用调用API申请堆内存的方法实现,但此种方法过于繁琐。联系到fb支持调用c函数的特点,我想到了malloc函数。
我们定义链表节点类型为LNode,包括一个_next指针和数据域data。用malloc函数每次申请大小为sizeof(LNode)的内存,通过List_Create()方法生成链表头指针pHead,之后就可以愉快的进行各种方法的编写了

malloc函数讲解

百度上对malloc的解释比较生僻难懂,这里我讲解一下我的思路。malloc就是动态地申请一块指定大小内存,并返回其指针(void指针)。因为是void*类型,如果我们想操作这块内存就要进行类型转换,也就要用到Cast(欲转换成的类型,变量)将void指针转换成LNode ptr。
想要使用malloc必须包含以下库

 #Include Once "crt\stdlib.bi"

LNode类型

Type LNode
    _data As Long
    _next As LNode Ptr 
End Type

List_Create()的实现

先上代码

Function List_Create() As LNode Ptr 
  Dim As LNode Ptr pHead,pTail
  pHead = Cast(LNode Ptr, malloc(SizeOf(LNode)))
  If (pHead = Null) Then
      List_Create = Null  
  End If 
  pTail = pHead
  pTail-> _next = Null
  List_Create = pTail 
End Function 

首先定义头指针,并为其申请内存空间,pHead=Null是对malloc是否申请成功的特判,其实这里的Ptail指针完全不需要(尾指针的next为Null),这里这样写是为了让大家更好地理解这个过程(链表头指针与尾指针重叠,链表为空)

List_AddNode(_data)的实现

与Create函数原理类似,此函数是向链表尾部添加一个节点。

Function List_AddNode(pHead As LNode Ptr, _data As Long) As BOOL  
  Dim As LNode Ptr p
  Dim As LNode Ptr newN 
  p = pHead  
  Do While p-> _next <> Null
      p = p-> _next  
  Loop  
  newN = Cast(LNode Ptr, malloc(SizeOf(LNode)))
  newN-> _data = _data
  newN-> _next = p-> _next  
  p-> _next = newN  
  List_AddNode =True 
End Function

先通过一个while循环获取尾指针,再将尾指针的next指向新节点,新节点的next赋值为Null,将数值data存进新节点。大功告成。

List_DeleteAll(pHead)的实现

有创造就有销毁,此函数的功能是释放所有链表节点。

Function List_DeleteAll(pHead As LNode Ptr) As BOOL 
  Dim As LNode Ptr p,q
  p = pHead-> _next  
  q = pHead  
  free(q)
  Do While p-> _next <> Null
      q = p
      p = p-> _next 
      free(q)  
  Loop  
  free(p)
  List_DeleteAll =True 
End Function 

感谢强大的C,我们再次需要调用C函数。free()函数的作用就是释放一个指针。这里通过循环逐个释放,其余原理同上,不过多解释。

List_InsertNode(pHead,id,_data)的实现

将_data插入指定链表的第id位置

Function List_InsertNode(pHead As LNode Ptr, id As Long, _data As Long) As BOOL
  Dim As LNode Ptr p=pHead
  Dim As Long i
  For i = 1 To id -1
      p = p-> _next  
  Next i
  Dim As LNode Ptr q
  q = p
  Dim As LNode Ptr inode
  inode = Cast(LNode Ptr, malloc(SizeOf(LNode)))
  p = p-> _next 
  inode-> _next = p
  q-> _next = inode
  inode-> _data = _data
  List_InsertNode = True 
End Function

这里我主要讲解一下插入的过程。因为要插入到id位置,也就是向第id-1个节点后插入(在第id个节点前插入)。所以,我们先用循环获取第id-1个节点的指针,并用指针q存下,再获取当前第id个节点的指针。新节点的next指针指向p,q的next指向inode,此时inode节点即为第id个节点。

List_DeleteNode(pHead,id)的实现

删除指定位置的节点,原理互逆

Function List_DeleteNode(pHead As LNode Ptr, id As Long) As BOOL
  Dim As LNode Ptr p=pHead
  Dim As Long i 
  For i = 1 To id-1
      p = p-> _next 
  Next i
  If p = Null Then  
      Return False 
  End If 
  Dim As LNode Ptr q
  q = p
  p = p-> _next 
  q-> _next = p-> _next  
  free(p)
  List_DeleteNode =True 
End Function 

拓展:获得链表长度函数的实现

遍历一遍,即可得出长度

Function List_GetLength(pHead As LNode Ptr) As Long 
  Dim As LNode Ptr p=pHead
  Dim As Long i
  i = 0
  Do While p-> _next <> Null
      p = p-> _next 
      i=i+1
  Loop 
  List_GetLength = i 
End Function

总结

当然,这里还有很多功能我没有实现(比如find函数),特殊情况的判断也不全面,但原理都是一致的。希望广大fb爱好者能在我的基础上完善链表的操作,同时提高编程技术。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我会尽力回答你的问题。 首先,WinHook 是一个用于Windows操作系统的钩子库,它允许你监视和控制系统中发生的事件。使用WinHook,你可以捕捉和处理各种系统事件,如键盘和鼠标输入,窗口消息等。 要实现在按下Home键时呼出隐藏窗口,你需要创建一个钩子函数来捕捉Home键的按下事件。以下是一个基本的WinHook钩子函数的示例代码: ``` ' 定义钩子回调函数 Declare Function HookProc Lib "user32.dll" Alias "CallNextHookEx" (ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long ' 定义钩子ID常量 Const WH_KEYBOARD_LL = 13 ' 定义键盘事件常量 Const WM_KEYDOWN = &H100 Const WM_SYSKEYDOWN = &H104 ' 定义键盘事件数据结构 Type KBDLLHOOKSTRUCT vkCode As Long scanCode As Long flags As Long time As Long dwExtraInfo As Long End Type ' 声明全局变量 Dim hHook As Long ' 钩子回调函数 Function KeyboardHook(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Dim HookData As KBDLLHOOKSTRUCT If nCode = HC_ACTION Then If wParam = WM_KEYDOWN Or wParam = WM_SYSKEYDOWN Then ' 捕捉Home键按下事件,显示隐藏窗口 HookData = ByVal lParam If HookData.vkCode = vbKeyHome Then ' 显示隐藏窗口的代码 ... End If End If End If ' 调用下一个钩子函数 KeyboardHook = HookProc(nCode, wParam, lParam) End Function ' 安装钩子函数 Function InstallHook() As Boolean hHook = SetWindowsHookEx(WH_KEYBOARD_LL, AddressOf KeyboardHook, App.hInstance, 0) If hHook <> 0 Then InstallHook = True Else InstallHook = False End If End Function ' 卸载钩子函数 Function UninstallHook() As Boolean If UnhookWindowsHookEx(hHook) <> 0 Then UninstallHook = True Else UninstallHook = False End If End Function ``` 在上面的代码中,我们定义了一个名为KeyboardHook的钩子回调函数,用于捕捉按键事件。在钩子回调函数中,我们检查按键事件的vkCode是否为vbKeyHome,如果是,就执行显示隐藏窗口的代码。 要安装钩子函数,我们调用SetWindowsHookEx函数,并将WH_KEYBOARD_LL作为钩子类型传入。要卸载钩子函数,我们调用UnhookWindowsHookEx函数,传入钩子句柄hHook。 以上是使用WinHook控件实现在按下Home键时呼出隐藏窗口的基本代码示例,你可以根据自己的需要进行修改和完善。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值