数据结构基础--线性表的链式存储(单链表)

链表概述

链表是一种很常见的数据结构,它的元素个数不受限制,当进行添加元素的时候存储的个数会随之改变,链表的优点:在运行时确定大小,能够快速的插入和删除数据,链表的缺点:不能随机访问,用户必须提供编程支持
链表分为单链表,单向循环链表、双链表、双向循环链表,这篇文章主要讲述的是单链表。

在学习单链表之前我们先来了解几个概念性内容
  • 头结点:头结点的数据域可以不存储任何信息,头结点的域存储指向第一个结点的指针(即第一个元素结点的存储位置)。头结点的作用是使所有非空,并使对的插入、删除操作不需要区分是否为空表或是否在第一个位置进行,从而与其他位置的插入、删除操作一致。添加头结点能够更加方便的解决单链表的删除和插入操作,便于对首元结点进行处理,所以本篇文章在设置头结点的情况下进行的。

  • 首指针:它是指向链表中的第一个结点的指针。若链表设有头结点,则头指针所指结点为线性表的头结点;若链表不设头结点,则头指针所指结点为该线性表的首元结点。

单链表的常规操作(以下内容仅考虑常规条件下操作)

1.首先我们根据个人习惯,对一些类型进行重命名,和设置一些宏定义

#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OK 1
#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status;/* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int ElemType;/* ElemType类型根据实际情况而定,这里假设为int */

//定义结点
typedef struct Node{
    ElemType data;//数据域
    struct Node *next;//指针域
}Node;
typedef struct Node * LinkList;

2.单链表的初始化

//初始化单链表
Status InitLinkList(LinkList *L)
{
//生成一个结点作为头结点
    *L = (LinkList)malloc(sizeof(Node));
    if (*L ==NULL) {
        return ERROR;
    }
    (*L)->next = NULL;
    return OK;
}

3.单链表的插入:在指定位置插入数据

Status LinkListInsert(LinkList *L,int i , ElemType data){
  LinkList p,s;
  p  = *L;
  int  j  = 1;
//先找到插入的前一个位置
  while (p&&j<i) {
      p = p->next;
      ++j;
  }
//如果p为空或者j>i就不能再插入了
  if (!p||j>i) {
      return ERROR;
  }
//创建一个新的结点
  s = (LinkList)malloc(sizeof(Node));
//新节点赋值
  s->data = data;
//将新节点的next指向前一个结点p的next
  s->next = p->next;
//将p的next指向新的结点
  p->next = s;
  return OK;
}

4.单链表的删除,删除指定位置的数据,删除的思路,先找到首元结点,遍历找到要删除的前一个结点,记录下要删除的结点,将删除结点的前一个节点的next指向删除结点的下一个结点q->next,free删除节点的存储空间,这样完成了删除结点的操作。

Status ListDelete1(LinkList *L,int i,ElemType *e){
    LinkList p,q;
    int j=1;
//先找到首元结点
    p = (*L)->next;
//遍历找到要删除的前一个结点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    //记录下要删除的结点
    q=p->next;
//将删除结点的前一个节点的next指向删除结点的下一个结点q->next
    p->next = q->next;
//free删除节点的存储空间
    free(q);
    return OK;
}

5.单链表的取值,取出指定位置i,上的数据,使用指针来让外界获取该数据。

Status GetElem(LinkList L,int i,ElemType *e){
    int j;
//获取首元结点
    LinkList p = L->next;
    j=1;
//先找到i 位置的前一个结点
    while (p && j < i) {
        p = p->next;
        ++j;
    }
    if (!p || j >i) {
         return  ERROR;
    }
//获取数据
    *e = p->data;
    
    return OK;
}

6.单链表的遍历

void show(LinkList L){
//先找到首元结点
    LinkList p = L->next;
//遍历单链表
    while (p) {
//打印结点的数据
        printf("%d",p->data);
        p = p->next;
    }
    printf("\n");
}

下面讲一下单链表的另外两种插入结点方法:头插法、尾插法

  • 头插法:每次插入结点都是从链表的头部插入,单链表L插入随机数
    1.创建一个头结点
    2.头结点的next为空
    3.循环插入随机数据
    4.创建新节点,赋值
    5.将头结点的next指向p
void LinkListInsert(LinkList *L, int n){
    LinkList p;
//创建一个头结点
    (*L) = (LinkList)malloc(sizeof(Node));
//头结点的next为空
    (*L)->next = NULL;
 //循环插入随机数据
    for (int i= 0; i<n; i++) {
//创建新节点
        p = (LinkList)malloc(sizeof(Node));
//新节点的next为(*L)->next
        p->next =(*L)->next;
//赋值
        p->data = i;
//将头结点的next指向p
        (*L)->next = p;
    }
}
  • 尾插法:每次插入的结点都是从链表的尾部插入
    1.创建一个头结点
    2.将尾指针指向链表*L
    3.循环插入随机数据
    4.创建新节点
    5.尾指针的next指向新的结点
    6.将新节点赋值给尾指针
    7.将尾指针的next置为空
void LinkListInsert(LinkList *L, int n){
    LinkList p,r;
//创建一个头结点
    (*L) = (LinkList)malloc(sizeof(Node));
//将尾指针指向链表*L
    r=*L;
 //循环插入随机数据
    for (int i= 0; i<n; i++) {
//创建新节点
        p = (LinkList)malloc(sizeof(Node));
        p->data = i;
//尾指针的next指向新的结点
        r->next = p;
//将新节点赋值给尾指针
        r=p;
    }
//将尾指针的next置为空
r->next=NULL;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342