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

原创 2013年12月08日 23:01:24

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

理解几个常用术语:

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;
      }
    }
  }
}






线性结构--离散存储 链表讲解

数据结构大体成上可以分成两种: 1. 线性结构. 2. 非线性结构( 树,图) 1. 什么是线性结构        大概上可以这样定义: 加入所有的节点可以用一条直线连接起来. 就是线...
  • nvd11
  • nvd11
  • 2013年04月06日 16:26
  • 1040

数据结构C语言版线性链表的12个基本操作

线性链表的12个基本操作 分别是:构造 销毁 清空      判空  表长 取元      定位  前驱 后继      插入 遍历;在此为了好记我分别二字短语三三结合 ,接下来会一一解释。 头文件和...
  • WLxinliang
  • WLxinliang
  • 2016年10月14日 23:00
  • 3054

简单来说 数据结构有哪些? 存储方式上:链表形式,数组,

研究数据结构从三个方向进行 : 逻辑结构 存储结构 操作 简单来说 数据结构有哪些? 存储方式上:链表形式,数组, 数据结构分别为逻辑结构、存储结构(物理结...
  • dingxingmei
  • dingxingmei
  • 2015年06月12日 14:43
  • 2179

[数据结构]02-线性结构1 两个有序链表序列的合并

本题要求实现一个函数,将两个链表表示的递增整数序列合并为一个非递减的整数序列。 函数接口定义: List Merge( List L1, List L2 ); 其中List结构定义如下: typ...
  • sinat_37273780
  • sinat_37273780
  • 2017年03月14日 17:32
  • 242

数据结构之线性结构的离散存储(单链表)

离散存储 [链表] 定义: n个节点离散分配(数据域和指针域) 彼此通过指针相连 每个节点只有一个前驱结点,每个节点只有一个后续节点 首结点没有前驱结点,尾结点没有后续节点 专业术语:...
  • li_101357
  • li_101357
  • 2015年07月19日 16:52
  • 420

看数据结构写代码(52) 广义表的扩展线性链表存储表示

广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上。 这样 从 表头 一直 就可...
  • fuming0210sc
  • fuming0210sc
  • 2015年04月18日 21:24
  • 726

线性存储结构-LinkedList

LinkedList内部采用链表的形式构建,是一个双向链表。除了继承List外,还继承了Deque接口,可以当做堆栈结构使用。 private static final class Link { ...
  • junbin1011
  • junbin1011
  • 2016年11月14日 16:46
  • 1214

【数据结构】线性表的链式存储结构--单链表

单链表的创建、插入、删除等基本操作的实现
  • wupenm
  • wupenm
  • 2015年09月18日 10:12
  • 3035

【数据结构】单链表的基本操作

一、单链表基本概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。 二、单链表的基础用法 这里我们先讲一些简单的、基础的用法 如初始化,销毁,插入元素,求链表长度,打...
  • qq_31828515
  • qq_31828515
  • 2016年06月22日 17:54
  • 1796

单链表定义-(线性表的链表存储结构)

线性表分为:顺序存储结构和连存储结构 顺序存储结构的优点:     1.空间利用率高,几乎不需要额外的空间开销.     2.数据的逻辑结构和物理结构完全一致.     3.结点地址计算的时间...
  • forwardyzk
  • forwardyzk
  • 2016年12月08日 14:30
  • 1693
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:数据结构线性结构之离散存储--链表
举报原因:
原因补充:

(最多只允许输入30个字)