数据结构线性结构之离散存储--链表

链表是学习数据机构必须要掌握的知识,它是学习复杂数据结构的基础,如:二叉树,图等

理解几个常用术语:

1、首节点:第一个有效节点

2、尾节点:最后一个有效节点

3、头节点:没有存放有效数据,没有存放节点个数;设置头节点是因为对链表操作的时候,加上一个没有实际含义的头节点方便我们操作

4、头指向节点:指向头的节点

5、尾指向节点:指向尾的节点

一、链表的定义:

1、多个节点离散存储

2、彼此通过node(节点)相连

3、每个节点只有一个前驱节点,只有一个后续节点

4、首节点没有前驱节点,尾节点没有后续节点(循环链表除外)

先看一张图


根据上面的图,我们定义一个单向链表的节点Node

#include <stdio.h> // C语言
typedef struct node
{
   int data; // 有效数据
   struct node *pNext; // 指针数据,尾节点
}Node, *pNode;

class Node // PHP版
{
    private $Data;//节点数据
    private $Next;//下一节点
    public function setData($value){
        $this->Data=$value;
    }
    public function setNext($value){
         $this->Next=$value;
    }    
    public function getData(){
        return $this->Data;
    }
    public function getNext(){
        return $this->Next;
    }
    public function __construct($data,$next){
        $this->setData($data);
        $this->setNext($next);
    }
}
list{} // lua
function list:new()
    local l = { data = nil, next = nil }
    setmetatable(l, self)
    self.__index = self
    return l
end

二、创建一个单向链表

我们将节点创建好之后,就可以把多个节点连接起来,链表就创建好了

1、创建头节点

pNode pHead = NULL;
pHead = createlink(4);  //创建一个链表,有4个节点
traverslink(pHead); //遍历链表

2、链表的具体实现

pNode createlink(int len)
{
    int i;
    int val = 1; // 值
    pNode pHead = (pNode)malloc(sizeof(Node)); // 分配内存
    if (NULL == pHead)
    {
      exit(-1); // 失败退出
    }
    pNode pWei = pHead;
    pWei->pNext = NULL; // 永远处于尾节点
    for (i = 0; i < len; i++)
    {
       val = val + i;
       pNode pNew = (pNode)malloc(sizeof(Node));
       if (NULL == pNew)
       {
         exit(-1); // 分配内存失败,退出
       }
       pNew->data = val;
       pWei->pNext = pNew;
       pNew->pNext = NULL;
       pWei = pNew;
    }
    return pHead; // 返回头节点
}
void traverslink(pNode pHead) // 遍历
{ // 遍历非常简单,直接使用连接的节点
   pNode p = pHead->pNext;
   while (NULL != p)
   {
     printf("%d ", p.data);
     p = p->pNext;
   } 
   printf("\n");
}
下面是PHP和Lua创建链表和遍历链表

class LinkList  {   // PHP版,这里我们只需要设置头节点就可以了,然后根据头节点新增、插入...   
 private $header;//头节点      
 public function setHeader($value){          
  $this->header=$value;      
 }      
 public function getHeader(){          
  return $this->header;      
 }     
 public function __construct(){ 
  $this->setHeader(new Node(null,null)); //设置头节点
 } 
 //遍历节点 
 public function get()      
 {          
  $node=$this->header;          
  if($node->getNext()==null){              
   print("数据集为空!");              
   return;          
  }          
  while($node->getNext()!=null)          
  {              
   print($node->getNext()->getData());              
   if($node->getNext()->getNext()==null){break;}              
   $node=$node->getNext();                   
  }               
 }       
}
function list:lprint() // lua遍历链表,这里不需要创建链表,在我们设置节点的时候直接调用就创建了
  local l = self
  while l.next do
    print(l.data)
    l = l.next
  end
end

4、链表新增好之后,就可以实现判断是否为空,新增,删除..


BOOL isEmpty(pNode pHead) // 在C语言中是没有Bool类型的,只能使用宏定义使用
{
  if (NULL == pHead->pNext)
    return TRUE;
  else
    return FALSE;
}
int length(pNode pHead)
{
   int len = 0;
   pNode p = pHead->pNext;
   while (NULL != p)
   {
     p = p->pNext;
     len = len + 1;
   }
   return len;
}
BOOL insert(pNode pHead, int pos, int val)
{
    int i = 0;
    pNode p = pHead;
    while (NULL !=p && i<pos-1)
    {
       p = p->pNext;
       ++i;
    }
    if (i > pos-1 || NULL == p)
       return FALSE;
    pNode pNew = (pNode)malloc(sizeof(Node));
    pNew->data = val;
    pNode q = p->pNext;
    p->pNext = pNew;
    pNew->pNext = q;
    return TRUE;
}
BOOL delete(pNode pHead, int pos, int *pVal)
{

    int i = 0;
    pNode p = pHead;
    while (NULL !=p && i<pos-1)
    {
       p = p->pNext;
       ++i;
    }

    if (i > pos-1 || NULL == p)
       return FALSE;

    pNode q = p->pNext;
    *pVal = q.data;
    p->pNext = p->pNext->pNext;
    free(q);
    q = NULL;
    return true;
}
void sort(pNode pHead)
{
  int len = length(pHead);
  int i, j, t;
  pNode p, q;
  for (i = 0, p=pHead->pNext; i < len - 1; ++i, p = p->pNext)
  {
    for(j = j+1, q=p->pNext; j< len; ++j, q=q->pNext)
    {
      if (p->data > q->data)
      {
        t = p->data;
        p->data = q->data;
        q->data = t;
      }
    }
  }
}






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值