五、线性表(2)

原创 2016年08月30日 15:13:11

1、线性表链式存储结构

我们把存储数据元素信息的域称为数据域,把存储直接后继位置的域称为指针域。指针域中存储的信息称为指针或链。这两部分信息组成数据元素称为存储映像,称为结点(Node)。
单链表:这里写图片描述
单链表的读取
获得链表第i个数据的算法思路:

  • 声明一个结点p指向链表第一个结点,初始化j从1开始;
  • 当j < i 时,就遍历链表,让p的指针向后移动,不断指向下一结点,j+1;
  • 若到链表末尾p为空,则说明第i个元素不存在;
  • 否则查找成功,返回结点p的数据。
status getelem(linklist L,int i,elemtype *e)
{
    int j;
    linklist p;
    p=L->next;
    j=1;
    while(p&&j<i)
    {
        p=p->next;
        ++j;
    }
    if(!p||j>i)
    {
        return error;
    }
    *e=p->data;
    return OK;
}

单链表的插入
单链表第i个数据插入结点的算法思路:

  • 声明一个结点p指向链表第一个结点,初始化j从1开始;
  • 当j < i 时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
  • 若到链表末尾p为空,则说明第i个元素不存在;
  • 否则查找成功,在系统中生成一个空结点s;
  • 将数据元素e赋值给s->data;
  • 单链表的插入两个标准语句;
    s->next=p->next;
    p->next=s;
  • 返回成功。
status listinsert(linklist *L,int i,elemtype e)
{
    int j;
    linklist p,s;
    p=*L;
    j=1;
    while(p&&j<i)//用于寻找第i个结点
    {
        p=p->next;
        j++;
    }
    if(!P||j>i)
    {
        return error;
    }
    s(linklist)malloc(sizeof(node));
    s->data=e;
    s->next=p->next;
    p->next=s;
    return OK;
}

单链表的删除
如图,上为单链表的插入,下为删除:
这里写图片描述
单链表第i个数据删除结点的算法思路:

  • 声明一个结点p指向链表第一个结点,初始化j从1开始;
  • 当j < i 时,就遍历链表,让p的指针向后移动,不断指向下一结点,j累加1;
  • 若到链表末尾p为空,则说明第i个元素不存在;
  • 否则查找成功,将欲删除结点p->next赋值给q;
  • 单链表的删除标准语句p->next=q->next;
  • 将q结点中的数据赋值给e,作为返回;
  • 释放q结点。
status listdelete(linklist *L,int i,elemtype *e
{
    int j;
    linklist p,q;
    p=*L;
    j=1;
    while(o->next&&j<i)
    {
        p=p->next;
        ++j;
    }
    if(!(p->next)||j>i)
    {
        return error;
    }
    q=p->next;
    p->next=q->next;
    *e=q->data;
    free(q);
    return OK;
}

单链表的整表创建

  • 对于顺序存储结构的线性表的整表创建,我们可以用数组的初始化来直观理解。
  • 而单链表和顺序存储结构不一样,它的数据可以是分散在内存各个角落,它的增长也是动态的。
  • 对于每个链表来说,它所占用空间的大小和位置是不需要预先分配划定的,可以根据系统的情况和实际的需求即时生成。

    单链表整表创建的算法思路:

  • 声明一结点p和计数器变量i;

  • 初始化一空链表L;
  • 让L的头结点的指针指向NULL,即建立一个带头结点的单链表;
  • 循环实现后继结点的赋值和插入。

头插法建立单链表
头插法从一个空表开始,生成新结点,读取数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头上,直到结束为止。简单来说就是把新加进的元素放在表头后的第一个位置。

void createlisthead(linklst *L,int n)
{
    linklist p;
    int i;                          
    srand(time(0));//初始化随机数种子

    *L(linklist)malloc(sizeof(Node));
    (*L)->next=NULL;
    for(i=0;i<n;i++)
    {
        p=(linklist)malloc(sizeof(Node));//生成新结点
        p->data=rand()%100+1;
        p->next=(*L)->next;
        (*L)->next=p;
    }
}

尾插法建立单链表

void createlisttail(linklist *L,int n)
{
    linklist p,r;
    int i;
    srand(time(0));
    *L=(linklist)malloc(sizeof(Node));
    r=*L;
    for(i=0;i<n;i++)
    {
        p=(Node*)malloc(sizeof(Node));
        p->data=rand()%100+1;
        r->next=p;
        r=p;
    }
    r-<next=NULL;
}

单链表的整表删除
单链表整表删除的算法思路:

  • 声明结点p和q;
  • 将第一个结点赋值给p,下一结点赋值给q;
  • 循环执行释放p和将q赋值给p的操作。
status clearlist(linklist *L)
    {
        linklist p,q;
        p=(*L)->next;
        while(p)
        {
            q=p->next;
            free(p);
            p=q;
        }
        (*L)->next=NULL;
        return OK;
    }

2、单链表结构与顺序存储结构优缺点

1、存储分配方式:
- 顺序存储结构用一段连续的存储单元依次存储线性表的数据元素。
- 单链表采用链式存储结构,用一组任意的存储单元存放线性表的元素。
2、 时间性能:
- 查找:
顺序存储结构O(1)
单链表O(n)
- 插入和删除
顺序存储结构需要平均移动表长一半的元素,时间为O(n)
单链表在计算出某位置的指针后,插入和删除时间仅为O(1)
3、空间性能:
- 顺序存储结构需要分配内存存储空间,分大了,容易造成空间浪费,分小了,容易发生溢出。
- 单链表不需要分配存储空间,只要有就可以分配,元素个数也不受限制。

结论
若线性表需要频繁查找,很少进行插入和删除操作时,宜采用顺序存储结构。
若需要频繁插入和删除时,宜采用单链表结构。

版权声明:本文为博主原创文章,未经博主允许不得转载。

线性表-顺序实现(2)

  • 2016年11月15日 20:32
  • 1.94MB
  • 下载

ch2-线性表.ppt

  • 2017年11月07日 20:54
  • 374KB
  • 下载

数据结构2----线性表顺序存储和链式存储的实现(霜之小刀)

所谓线性表,其实就是具有“线”一样性质的表,所谓线一样的性质,也就是具有n个数据元素的优先序列。其中n>=0...

数据结构2线性表

  • 2015年11月14日 15:57
  • 1009KB
  • 下载

chap2线性表

  • 2014年03月02日 19:46
  • 627KB
  • 下载

HNCU1323:算法2-1:集合union (线性表)

http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1323 题目描述 假设利用两个线性表LA和LB分别...

数据结构有关线性表(2)介绍

  • 2009年09月18日 22:39
  • 549KB
  • 下载

C++数据结构--线性表 例子2

/* 程序作者 :邱于涵 时间:2015年2月23日23:06:17 */ #include using namespace std; ///////线性表 ///// struct ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:五、线性表(2)
举报原因:
原因补充:

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