type
  PNode = ^Node;
  Node = record
    data  : Integer;
    FUper : PNode;
    FDown : PNode;
  end;  TmList = record
    FHead : PNode;
    FLast : PNode;
  end;var global_list : TmList;
插入链表:InsertInToList(ANode : PNode);
if global_list.FHead = nil then 
begin//如果链表表头为空时直接将链表头、尾节点设置成此记录
  ANode^.FUper := nil;
  ANode^.FDown := nil;
  global_list.FHead := ANode;
  global_list.FLast := ANode;
end
else//插入到链表尾
begin
  global_list.FLast^.FDown := ANode;
  ANode^.FUper := global_list.FLast;
  ANode^.FDown := nil;
  global_list.FLast := ANode;
end;删除链表节点:RemoveFromList(ANode : PNode);
if ANode = global_list.FHead then
begin//先判断是否是链表头节点
  if ANode = global_list.FLast then
  begin//此前链表只有一个节点而已,清空链表
    global_list.FHead := nil;
    global_list.FLast := nil;
  end
  else//此节点是头节点但不是尾节点
  begin
    global_list.FHead := ANode^.FDown;//链表头节点指向此节点的后继
    ANode^.FDown^.FUper := nil;//此节点后继的前驱改为空
  end;
end
else//此节点不是头节点
begin
  if ANode = global_list.FLast then//如果是尾节点的话修正新的尾节点
  begin
    global_list.FLast := ANode^.FUper;//链表尾指向此节点的前驱
    ANode^.FUper^.FDown := nil;//此节点前驱的后继设为空
  end
  else//处于链表中间的非头节点非尾节点
  begin
    ANode^.FUper^.FDown := ANode^.FDown;(程序运行一段时间之后在这里会出现内存访问错误,不知道为什么)
    ANode^.FDown^.FUper := ANode^.FUper;
  end;
end;访问链表(查找某一个节点):FindInList(ANode : PNode):Boolean;
var tmp : PNode;
tmp := global_list.FHead;
Result := false;
while tmp <> nil do
begin
  if tmp^.data = ANode^.data then
  begin
    Result := true;
    break;//找到之后跳出循环
  end;
  if tmp = global_list.FLast then
    break
  else
    tmp := tmp^.FDown;
end;
//程序运行一段时间之后会在访问链表时无限循环,不知道问题出在哪里,还望各位达人解惑一下。刚开始在论坛里逛,没有分,望见谅!

解决方案 »

  1.   

    感觉是Find函数写错了,输入应该是data,输出应该是指针
    Find函数并没有真正的将ANode指向你所要的节点,继续Remove的时候就会报错了另外移除节点的时候没看到有释放的代码
      

  2.   

    大概是这样:
    function FindInList(data: Integer): PNode;
    var
      tmp: PNode;
    begin
      tmp := global_list.FHead;
      Result := nil;
      while tmp  <>  nil do
      begin
        if tmp^.data = data then
        begin
          Result := tmp;
          break;//找到之后跳出循环
        end;
        if tmp = global_list.FLast then
          break
        else
          tmp := tmp^.FDown;
      end;
    end;
      

  3.   


    if ANode = global_list.FHead then 
    begin//先判断是否是链表头节点 
      if ANode = global_list.FLast then 
      begin//此前链表只有一个节点而已,清空链表 
        global_list.FHead := nil; 
        global_list.FLast := nil; 
      end 
      else//此节点是头节点但不是尾节点 
      begin 
        global_list.FHead := ANode^.FDown;//链表头节点指向此节点的后继 
        ANode^.FDown^.FUper := nil;//此节点后继的前驱改为空 
      end; 
    end 
    else//此节点不是头节点 
    begin 
      if ANode = global_list.FLast then//如果是尾节点的话修正新的尾节点 
      begin 
        global_list.FLast := ANode^.FUper;//链表尾指向此节点的前驱 
        ANode^.FUper^.FDown := nil;//此节点前驱的后继设为空 
      end 
      else//处于链表中间的非头节点非尾节点 
      begin 
        ANode^.FUper^.FDown := ANode^.FDown;//(程序运行一段时间之后在这里会出现内存访问错误) 
        ANode^.FDown^.FUper := ANode^.FUper;//
      end; 
    end;
      

  4.   

        ANode^.FUper^.FDown := ANode^.FDown;//(程序运行一段时间之后在这里会出现内存访问错误
        ANode^.FDown^.FUper := ANode^.FUper;//既然不是链表头也不是链表尾,那么它的前驱和后继应该是存在的,但为什么会出现内存访问错误的问题呢?
      

  5.   

    不行,还是自己用TThreadList来搞得了