线性表之单链表

Posted modesty-boy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线性表之单链表相关的知识,希望对你有一定的参考价值。

在学完线性表之后,总结一下顺序表的优缺点

优点

  • 无须为元素之间的逻辑结构增添额外的储存空间,自成一体。
  • 随机存取,十分方便。

缺点

  • 空间利用率不高,容易造成“碎片”。
  • 插入删除操作需要移动大量的元素。
  • 当线性表的长度变化较大时,难以确定储存空间的容量。

 

而单链表可以很好的弥补顺序表的这些缺点。

一、实现方式

typedef int Elemtype;
typedef struct Node
{
    Elemtype e;//数据域 
    struct Node *next;//指针域
} Node , *LinkList;

二、操作集

初始化

void createList( LinkList *L )
{
    *L = ( LinkList ) malloc ( sizeof(Node) );
    (*L)->next = NULL;
    (*L)->e = 0;
}

创建头结点,头结点储存表长。

创建整张表

void createListHead( LinkList *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->e = rand() % 100 + 1;
        p->next = (*L)->next;
        (*L)->next = p;
    } 
}

使用头插法创建一张n个1-100数的随机数表。

void createListTail( LinkList *L , int n )
{
    LinkList p,r;//p新节点指针,r尾指针 
    int i;//节点数目 
    srand(time(0));
    
    //创建头结点 
    *L = ( LinkList ) malloc ( sizeof(Node) );
    r = *L;//尾指针先指向头节点 
    
    for( i = 0 ; i < n ; i++ )
    {
        p = ( LinkList ) malloc ( sizeof(Node) );
        p->e = rand() % 100 + 1;
        r->next = p;
        r = p;//指向尾部 
    }
    r->next = NULL;//最后指向空 
} 

使用头插法创建一张n个1-100数的随机数表。

读取

int getList( LinkList L , int i, Elemtype *e ) 
{
    //计数器 
    int j = 1;
    //指向第一个节点 
    LinkList p = L->next;
    
    while( p != NULL && j < i )
    {
        p = p->next;
        j++;
    }
    
    /*第i个元素不存在*/
    if( !p || j > i )
    {
        return 0;
    }
    
    *e = p->e;
    return 1;  
}

插入操作

int insertList( LinkList *L , int i , Elemtype e )
{
    int j = 1;
    LinkList p = *L;
    
    while( p && j < i )
    {
        p = p->next;
        j++;
    }
    
    //该位置不存在,超过表长或者为负数 
    if( !p || j > i )
    {
        return 0;
    }
    
    LinkList s = ( LinkList ) malloc ( sizeof(Node) );
    s->e = e;
    s->next = p->next;
    p->next = s;
    (*L)->e+=1;
    return 1;
}

 

 

步骤见下图,注意顺序,一步错步步错。

 

 

 技术图片

删除操作

int deleteList( LinkList *L , int i , Elemtype *e )
{
    int j = 0;
    LinkList q,p;
    
    p = *L;//头指针赋值
    j = 1;
    
    //找到被要删除元素的上一个元素 
    while( p->next && j < i )
    {
        p = p->next;
        j++;
    }
    
    /*第i个元素不存在*/ 
    if( !(p->next) || j > i )
    {
        return 0;
    }
    
    q = p->next;
    p->next = p->next->next;
    *e = q->e;
    free(q);
    
    return 1;
}

删除节点的过程,看图更容易理解

 技术图片

 

遍历操作

void printList( LinkList L )
{
    LinkList p = L->next;
    while( p )
    {
        printf("%d ",p->e);
        p = p->next;
    }
    printf("
打印完成");
}

清空操作

int ClearList( LinkList *L )
{
    LinkList p,q;
    p = (*L)->next;//指向第一个节点
    
    while( p!=NULL )
    {
        q = p->next;
        free(p);
        p = q;
    } 
    (*L)->next = NULL;
    return 1;
}

主函数

int main()
{
    Node *L;
    Elemtype a;
    
    createListHead(&L,10);
    printList(L);
    
    return 0;
}

 

 

纸上得来终觉浅,绝知此事要躬行

——陆游

 

以上是关于线性表之单链表的主要内容,如果未能解决你的问题,请参考以下文章

线性表之单链表

Java 大话数据结构 线性表之单链表

线性表之单链表实现

Java 大话数据结构 线性表之单链表

算法习题---线性表之单链表逆序打印

数据结构学习总结 线性表之单链表