FreeBasic
Главная
Вход
Регистрация
Пятница, 29.03.2024, 17:40Приветствую Вас Гость | RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Freebasic » Исходники » Связанный список (Связанный список)
Связанный список
haavДата: Пятница, 15.06.2012, 13:05 | Сообщение # 1
Генералиссимус
Группа: Администраторы
Сообщений: 1361
Репутация: 49
Статус: Offline
Связанный список


Пример связанного списка, в котором возможно добавление, удаление, вставка, перемещение элементов. Автор: Quinton Roberts

Code
' Program:  Link List Example Source Code
' Version:  0.01
' Language: FreeBASIC (v0.18.3b)
' Author:   Quinton Roberts (Eclipzer)
' Date:     04-16-08
' Update:   04-17-08
'
' Copyright (c) 2008.

type nodedat
  as string      id      'user-defined id for nodes
  as any     ptr dataptr 'pointer to node data
  as any     ptr listptr 'pointer to list (any pointer allows variable list types)
  as nodedat ptr nextptr 'pointer to next node
  as nodedat ptr prevptr 'pointer to previous node
  declare destructor()
end type

type listdat
  as ulongint     count   'list node count
  as nodedat  ptr nodeptr 'pointer to current node
  as nodedat  ptr front   'pointer to first node
  as nodedat  ptr last    'pointer to last node
  declare sub      append(byref nodeptr as nodedat ptr)
  declare sub      clear()
  declare sub      insert(byref nodeptr as nodedat ptr,index as ulongint=0)
  declare sub      move(byref source as nodedat ptr,target as ulongint)
  declare sub      move(source as ulongint,target as ulongint)
  declare sub      move(id as string,target as ulongint)
  declare function node_idx(nodeptr as nodedat ptr) as ulongint
  declare function node_idx(id as string) as ulongint
  declare function node_ptr(index as ulongint) as nodedat ptr
  declare function node_ptr(id as string) as nodedat ptr
  declare function remove(nodeptr as nodedat ptr) as nodedat ptr
  declare function remove(index as ulongint) as nodedat ptr
  declare function remove(id as string) as nodedat ptr
  declare destructor()
  declare sub print()
end type

declare function node_create(bytes as ulongint=0,id as string="") as nodedat ptr
declare sub      node_delete(byref nodeptr as nodedat ptr)

dim as listdat     myList
dim as nodedat ptr myNode

for i as integer=0 to 3
  myNode=node_create(0,"node"+str$(i+1))
  myList.append(myNode)
next

? "Generating initial list..."
?
? "List node count: "; myList.count
?
myList.print
sleep

dim as integer index1,index2

index1=2
myNode=node_create(0,"nodeX") 'create node X
myList.insert(myNode,index1)  '

?
? "Inserting "; myNode->id; " into list at index"; index1; "..."
?

? "List node count: "; myList.count

?
myList.print
sleep

?
myNode=myList.node_ptr("nodeX")
index1=myList.node_idx(myNode)
index2=4
? "moving "; myNode->id; " from index"; index1; " to index"; index2;"..."

myList.move(myNode,index2)

?
myList.print
sleep

?
? "Clearing list...":  myList.clear
? "List node count: "; myList.count
? "List cleared!!!"

sleep

' node destructor
destructor nodedat: node_delete(@this): end destructor

' =============================================================================
'          Name: node_create (04.16.08)
'       Returns: node pointer
'    Parameters:
'       [bytes]: bytes to allocate to node data pointer [0]
'          [id]: user-defined node ID [""]
' -----------------------------------------------------------------------------
'   Description: Creates a node in memory for subsequent insertion into a
'                linked list. If successful, returns a pointer to the node.
'      Comments: CALLOCATE() will set the node elements to zero (null pointers).
'                Node's data pointer is a null pointer if bytes = 0.
' =============================================================================
function node_create(bytes as ulongint,id as string) as nodedat ptr

  dim nodeptr as nodedat ptr      'create node pointer

  nodeptr=callocate(len(nodedat)) 'create empty node

  nodeptr->id=id     'store node ID
  nodeptr->listptr=0 'null list pointer
  nodeptr->prevptr=0 'null prev pointer
  nodeptr->nextptr=0 'null next pointer

  ' allocate cleared memory to node if requested bytes > 0
  if bytes then nodeptr->dataptr=callocate(bytes)

  return nodeptr

end function

' =============================================================================
'          Name: node_delete (04.16.08)
'       Returns:
'    Parameters:
'       nodeptr: pointer to node to delete from memory
' -----------------------------------------------------------------------------
'   Description: Deletes a node from memory.
'      Comments: Be certain to destroy all references to a node before deleting.
'                Node pointer is set to null after deallocating.
' =============================================================================
sub node_delete(byref nodeptr as nodedat ptr)
  if nodeptr then                  'if valid node pointer...
   if nodeptr->listptr then       'if attached to a list...
    cptr(listdat ptr,nodeptr->listptr)->remove(nodeptr) 'remove it!
   end if
   if nodeptr->dataptr then       'if valid data pointer...
    deallocate(nodeptr->dataptr) 'delete node data from memory
   end if
   deallocate(nodeptr)            'delete node from memory
   nodeptr=0                      'set null pointer
  end if
end sub

' list destructor
destructor listdat: this.clear: end destructor

' =============================================================================
'          Name: .append (04.16.08)
'       Returns:
'    Parameters:
'       nodeptr: pointer to node to append
'          list: list to append node to
' -----------------------------------------------------------------------------
'   Description: Add a node to the end of a linked list.
'      Comments:
' =============================================================================
sub listdat.append(byref nodeptr as nodedat ptr)

  if nodeptr=0 then return 'exit if node is a null pointer

  ' remove node from attached list before modifying it
  if nodeptr->listptr then
   cptr(listdat ptr,nodeptr->listptr)->remove(nodeptr)
  end if

  ' if the list contains nodes, we simply link the new node to the last node.
  ' otherwise we need to make the new node the first node and keep its pointer
  ' as the list pointer.
  if front then           'if nodes present...
   nodeptr->prevptr=last 'link new node to last node
   last->nextptr=nodeptr 'update rear node to point to new node
   last=nodeptr          'update rear pointer
  else                    'if list empty...
   nodeptr->prevptr=0    'front node has no prev node so make it a null pointer
   front=nodeptr         'update front pointer
   last =nodeptr         'update last pointer
  end if

  nodeptr->listptr=@this 'store list pointer with node
  nodeptr->nextptr=0     'end the list by making next pointer a null pointer

  count+=1 'update list node count

end sub

' =============================================================================
'          Name: .clear (04.16.08)
'       Returns:
'    Parameters:
' -----------------------------------------------------------------------------
'   Description: Remove and delete all nodes from a list.
'      Comments: The list is cleared by repeatedely removing the front node
'                until no nodes remain. Be certain to destroy all references to
'                list nodes before clearing the list.
' =============================================================================
sub listdat.clear()
  do while front
   node_delete(remove(front))
  loop
end sub

' =============================================================================
'          Name: .insert (04.16.08)
'       Returns:
'    Parameters:
'       nodeptr: pointer to node to insert
'         [idx]: index to insert into list [0]
' -----------------------------------------------------------------------------
'   Description: Insert node into list at specified index.
'      Comments: Insert front if index <= 0
'                Insert rear if index >= node count
' =============================================================================
sub listdat.insert(byref nodeptr as nodedat ptr,index as ulongint)

  if nodeptr=0 then return 'exit if node is a null pointer

  ' remove node from attached list before modifying it
  if nodeptr->listptr then
   cptr(listdat ptr,nodeptr->listptr)->remove(nodeptr)
  end if

  dim as ulongint nodeCount=1

  if front then 'if nodes present

   dim as nodedat ptr prev=0
   dim as nodedat ptr curr=front

   if index then
    do while curr
     if nodeCount=index then exit do 'index found!
     prev=curr
     curr=curr->nextptr
     nodeCount+=1
    loop
   end if

   if prev=0 then           'if front of list...
    nodeptr->prevptr=0     'point node prev to 0 (front node has no prev node)
    nodeptr->nextptr=front 'point node next to front node
    front->prevptr=nodeptr 'point front prev to node
    front=nodeptr          'make node the front node

   elseif curr=0 then       'if end of list
    nodeptr->nextptr=0     'point node next to 0 (last node has no next node)
    nodeptr->prevptr=last  'point node prev to last node
    last->nextptr=nodeptr  'point last next to node
    last=nodeptr           'make node the last node

   else                     'insert into list...
    nodeptr->prevptr=prev  'point node prev to prev
    nodeptr->nextptr=curr  'point node next to curr
    prev->nextptr=nodeptr  'point prev node to node
    curr->prevptr=nodeptr  'point curr node to node
   end if

  else                 'if no nodes in list...
   front=nodeptr      'point front to node
   last =nodeptr      'point last to node
   nodeptr->prevptr=0 'point node prev to 0 (front node has no prev node)
   nodeptr->nextptr=0 'point node next to 0 (last node has no next node)
  end if

  nodeptr->listptr=@this 'store list pointer with node
  count+=1               'update list count

end sub

' =============================================================================
'          Name: .move (04.16.08)
'       Returns:
'    Parameters: (source,target)
'        source: pointer, index or ID of node to remove
'        target: index to place removed node
' -----------------------------------------------------------------------------
'   Description: Reposition a node within a list, using a source node pointer,
'                index or ID and a target index. The node is first removed and
'                then it is reinserted into the list.
'      Comments: The source index must be within the list range in order for a
'                move to occur. If the target index is out of range, the node
'                will be placed in either the front or rear of the list.
' =============================================================================
sub listdat.move(byref source as nodedat ptr,target as ulongint)
  insert(remove(source),target) 'reinsert node into list
end sub

sub listdat.move(source as ulongint,target as ulongint)
  insert(remove(source),target) 'reinsert node into list
end sub

sub listdat.move(id as string,target as ulongint)
  insert(remove(id),target) 'reinsert node into list
end sub

' =============================================================================
'          Name: .node_idx (04.16.08)
'       Returns: node index
'    Parameters: (nodeptr)
'       nodeptr: node pointer of index to return
'            OR: (id)
'            id: node id of index to return
' -----------------------------------------------------------------------------
'   Description: Return the index of a node in a list using the node's pointer.
'      Comments: Return 0 if pointer is not in the list.
' =============================================================================
function listdat.node_idx(nodeptr as nodedat ptr) as ulongint

  dim as nodedat ptr curr=front 'create list pointer

  for index as ulongint = 1 to count
   if curr=nodeptr then return index
   curr=curr->nextptr
  next

  return 0

end function

function listdat.node_idx(id as string) as ulongint

  dim as nodedat ptr nodeptr=front 'create list pointer

  for index as ulongint = 1 to count
   if nodeptr->id=id then return index
   nodeptr=nodeptr->nextptr
  next

  return 0

end function

' =============================================================================
'          Name: .node_ptr (04.16.08)
'       Returns: node pointer
'    Parameters: (index)
'         index: index of node pointer to return
'            OR: (id)
'            id: ID of node pointer to return
' -----------------------------------------------------------------------------
'   Description: Return the pointer to a node at a specified list index. Return
'                a null pointer (0) if index out of range.
'      Comments: The first node in the list is index=1.
' =============================================================================
function listdat.node_ptr(index as ulongint) as nodedat ptr

  if index>count then return 0     'return null pointer if index out of range

  dim as ulongint    nodeCount=1
  dim as nodedat ptr nodeptr=front 'pointer to front of list

  do while nodeptr               'loop to find list node to remove
   if nodeCount=index then exit do
   nodeptr=nodeptr->nextptr  'traverse next node
   nodeCount+=1              'update node count
  loop

  return nodeptr

end function

function listdat.node_ptr(id as string) as nodedat ptr

  dim as nodedat ptr nodeptr=front 'pointer to front of list

  for i as integer = 0 to count-1
   if nodeptr->id=id then return nodeptr 'exit if ids match
   nodeptr=nodeptr->nextptr              'traverse next node
  next

  return 0

end function

' =============================================================================
'          Name: .remove (04.16.08)
'       Returns: pointer to removed node
'    Parameters:
'       nodeptr: pointer to node to remove
' -----------------------------------------------------------------------------
'   Description: Remove a node from a list using node's pointer.
'      Comments: Since each node contains a list pointer, they can properly
'                remove themselves from their assigned list. This prevents any
'                attempt to remove a node from a list that it does not belong
'                to.
' =============================================================================
function listdat.remove(nodeptr as nodedat ptr) as nodedat ptr

  if nodeptr=0        then return 0 'exit if node invalid

  dim as listdat ptr listptr: listptr=cptr(listdat ptr,nodeptr->listptr)

  if listptr <> @this then return 0 'exit if node not in list

  'first node has a prev pointer is always 0
  'last node next pointer is always 0
  'if a list only has 1 node then its prev and next pointers will both be 0

  if (nodeptr->prevptr=0) and (nodeptr->nextptr=0) then 'if single node...
   this.nodeptr=0
   front=0
   last=0
  elseif (nodeptr->prevptr=0) then 'if first node...
   front=nodeptr->nextptr
   if front then front->prevptr=0 'start list
  elseif (nodeptr->nextptr=0) then 'if last node...
   last=nodeptr->prevptr
   if last then last->nextptr=0   'end list
  else
   nodeptr->prevptr->nextptr = nodeptr->nextptr 'connect prev pointer with next pointer
   nodeptr->nextptr->prevptr = nodeptr->prevptr 'connect next pointer with prev pointer
  end if

  nodeptr->prevptr=0 'assign removed node a null prev pointer
  nodeptr->nextptr=0 'assign removed node a null next pointer
  nodeptr->listptr=0 'assign removed node a null list

  count-=1  'decrement list node count

  return nodeptr 'return node pointer

end function

' =============================================================================
'          Name: .remove (04.17.08)
'       Returns: pointer to removed node
'    Parameters:
'         index: index of node to remove (1=first node)
' -----------------------------------------------------------------------------
'   Description: Remove a node from a list at a specified index position and
'                return a pointer to it. Return a null pointer (0) if index
'                out of range.
'      Comments: The first node in the list is index=1.
' =============================================================================
function listdat.remove(index as ulongint) as nodedat ptr

  if (index=0) or (index>count) then return 0 'return null pointer if index out of range

  dim as ulongint    nodeCount=1
  dim as nodedat ptr nodeptr=front 'pointer to front of list

  do while nodeCount<index    'loop to find list node to remove
   if nodeptr=0 then exit do 'exit at end of list
   nodeptr=nodeptr->nextptr  'traverse next node
   nodeCount+=1              'update node count
  loop

  remove(nodeptr)

  return nodeptr 'return pointer to removed node

end function

function listdat.remove(id as string) as nodedat ptr

  dim as nodedat ptr nodeptr=front 'pointer to front of list

  do while nodeptr                 'loop while valid node
   if nodeptr->id=id then exit do 'exit loop if ID match found
   nodeptr=nodeptr->nextptr       'traverse next node
  loop

  remove(nodeptr) 'remove node

  return nodeptr  'return pointer to removed node

end function

sub listdat.print

  dim as nodedat ptr nodeptr

  nodeptr=front
  for i as integer=1 to count
   ? nodeptr->id
   nodeptr=nodeptr->nextptr
  next

end sub


Вы сохраняете власть над людьми покуда оставляете им что-то…Отберите у человека все, и этот человек уже будет неподвластен вам…
 
Форум » Freebasic » Исходники » Связанный список (Связанный список)
  • Страница 1 из 1
  • 1
Поиск: