定义

线性表的链式存储又称单链表,它是指通过任意的存储单元来存储线性表的数据。注意此时的数据在物理地址上不在连续,内存是动态分配的,而且数据是存放在结点中,结点组成链表,每个节点分为数据域和指针域,所以我们在定义的时候,数据域来存放数据,指针域存放后面结点的地址(因为地址不连续。必须有一个变量来知道下一个结点在哪里)
代码描述:

typedef int ElemType;
typedef struct LNode {ElemType data;struct LNode* Next;
}LNode,*LinkList;

特点

  • 可以解决顺序表需要大量连续存储空间的缺点
  • 单链表有指针域,我们只要存储数据,现在又存储了个指针,浪费了内存
  • 知道第i个位置,就知道后面所有的结点内容了,但不能知道前面的结点

基本操作

再说基本操作之前,我们先来了解头指针和头结点

  • 头指针:标识一个单链表
  • 头结点:第一个结点之前附加的一个结点,可有可无。头结点的数据域可以不设置任何信息,指针域指向第一个元素结点,就是数据域有存放我们要的数据的结点
  • 区别:头指针就是链表的名字,指向第一个结点,这个理解的时候,可以联想数组,数组名就是头指针。如果有头结点,假如数组名叫a,a[1]就是头结点,只是这个里面不存放数据,头指针指向头结点,头指针的值就是头结点的首地址,头结点的指针域的值是存放第一个数据的首地址

1、建立单链表
1.1头插法
假如现在链表只有一个数据是1,按照头插法在插入数据2,那么现在的数据是2,1,第一个数据是2,这就是头插法

/*
头插法建立单链表,将新的数据插入当前链表的表头
*/LinkList List_HeadInsert(LinkList& L) {LNode* s;  int x;L = (LinkList)malloc(sizeof(LNode)); //创建头结点L->next = NULL;scanf("%d", &x);while (x != 9999)                      //输入9999表示结束{s = (LNode*)malloc(sizeof(LNode));    //创建新的结点s->data = x;s->next = L->next;L->next = s;scanf("%d", &x);}return L;
}

我们知道头结点L是第一个结点,里面不存放数据,所以我们在插入数据s时,只需将头结点L的指针域的值赋值给新插入数据S的指针,这样新插入的数据S就指向头指针L指向的结点,现在新插入的结点s和头结点L都指向了一个结点,相当于两个头结点了,但头结点只能有一个,所以我们的L还要指向S,始终保证L都是第一个节点,s就是第一个带有我们存放数据的结点

1.2 尾插法

/*
尾插法:在尾部插入数据
*/
LinkList List_TailInsert(LinkList& L) {int x;L = (LinkList)malloc(sizeof(LNode));LNode* s, * r = L;       //r为表尾指针scanf("%d", &x);while (x != 9999)        //输入9999表示结束{s = (LNode*)malloc(sizeof(LNode));s->data = x;r->next = s;r = s;scanf("%d", &x);}r->next = NULL;return L;
}

此时多了个r指针,r始终表示最后一个结点,它的值是最后一个结点的首地址,我们插入一个新结点s时,尾插法要把s放到数据最后,没有插入s前,r表示最后一个结点,所以让r的指针域指向s,r现在是倒数第二个结点,但r始终表示最后一个结点,所以要把r指向s

1.3 尾插法和头插法

  • 尾插法生成的链表结点的次序与输入数据的顺序相同,而头插法不一致
  • 每个结点插入的时间为0(1),链表表长为n,则时间复杂度为0(n)
  • 头插法的L始终表示头结点,尾插法的r始终要表示最后一个结点

2、按序号查找结点值
思路:从第一个节点出发,顺指针next依次往下找,当找到第i个结点结束,否则返回null

/*按序号查找结点值:
*/
LNode* GetElem(LinkList L, int i) {int j = 1;      //计数LNode* p = L->next;if (i <= 0)return NULL;while (p && j < i) {p = p->next;j++;}return p;
}

头结点为第一个结点,不存放值,所以不必要查找,直接j=1就行,为什么要p&&j<i呢?因为我们在创建我们的链表时,没有定义变量来记录长度,所以我们就不知道链表的长度,当j<i,但已经超过链表的长度时,我们就不能查找下去了,刚好最后一个结点的next是null,能判断有没有到达最后一个结点

3、按值查找
返回第一个等于我们要查找值的结点

/*按照值来查找
*/LNode* LocateElem(LinkList L, ElemType e) {LNode* p = L->next;while (p != NULL && p->data!=e){p = p->next;}return p;
}

4、插入结点
将数据e插入到第i个结点上,首先判断i的合法性

/*
插入到第i个位置
*/bool Insert(LinkList& L, int i,ElemType e) {LNode* p = GetElem(L, i - 1);if (p != NULL) {LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = p->next;p->next = s;return true;}else{return false;}}

首先查找第i-1位置结点,为什么不是i呢?因为插入的时候,相当于第i个位置后移一步,所以第i-1的next要指向新插入的i位置,新插入的i位置要指向旧的i位置结点,如果查找i,就没办法知道i-1位置。根据查找i-1位置来判断i的合法性。如果不合法返回false

5、删除操作
将单链表的第i个结点删除。
思路:先判断删除位置的合法性,然后查找第i-1个结点,删除第i位置

/*
删除操作
*/bool Delete(LinkList& L, int i) {LNode* p = GetElem(L, i - 1);if (p != NULL) {LNode* q;q = p->next;p->next = q->next;free(q);return true;}else{return false;}
}

线性表----链式表相关推荐

  1. 线性表的定义与操作-顺序表,链式表(C语言)

    顺序表: typedef int Position; typedef struct LNode *List; struct LNode {ElementType Data[MAXSIZE];Posit ...

  2. 带头结点的链式表操作集

    6-6 带头结点的链式表操作集 (20 分) 本题要求实现带头结点的链式表操作集. 函数接口定义: List MakeEmpty(); Position Find( List L, ElementTy ...

  3. SCAU8579、SCAU8580、SCAU8581 链式表的基本操作

    这篇文章是一份纯代码分享. 代码包含了线性表的链式实现时的基本函数,包括: CreateLinkList.DestroyLinkList.ClearLinkList.LinkListEmpty.Lin ...

  4. 6-5 链式表操作集 (20分)

    本题要求实现链式表的操作集. 函数接口定义: Position Find( List L, ElementType X ); List Insert( List L, ElementType X, P ...

  5. 6-2 链式表的按序号查找

    6-2 链式表的按序号查找 (10 分) 本题要求实现一个函数,找到并返回链式表的第K个元素. 函数接口定义: ElementType FindKth( List L, int K ); 其中List ...

  6. 6-1 求链式表的表长

    6-1 求链式表的表长 (10 分) 本题要求实现一个函数,求链式表的表长. 函数接口定义: int Length( List L ); 其中List结构定义如下: typedef struct LN ...

  7. c语言实现数据结构中的链式表

    以下是我用c语言实现数据结构中的链式表 #pragma once; #ifndef _STDLIB_H #include <stdlib.h> #endif #ifndef _ELEMTY ...

  8. 6-1 求链式表的表长 (10 分)

    本题要求实现一个函数,求链式表的表长. 函数接口定义: int Length( List L ); 其中List结构定义如下: typedef struct LNode *PtrToLNode; st ...

  9. 线性表--链式实现方式

    清明节感冒了,休息了几天.前面实现了顺序方式的线性表,这篇文章笔者会简单的实现 链式方式的线性表. 在实现之前首先需要对其线性表的链式方式的特点做一个了解: 通俗的讲链式线性表就是元素之间逻辑相邻但是 ...

最新文章

  1. Activity的启动模式与flag详解
  2. Unet项目解析(2):./src/retinaNN_training.py
  3. Qt多线程 TCP 服务端
  4. 转,jquery中attr和prop的区别
  5. 深度残差收缩网络:(一)背景知识
  6. 诺基亚在日本测试5G网络 网速可达256MB/s
  7. Linux常用命令-2
  8. 跟着团子学SAP PS:项目计划成本与项目预算设计思路
  9. Linaro交叉编译链配置
  10. 日历查询---在线阴阳历转换器
  11. webpack-theme-color-replacer 路由跳转之后,样式丢失
  12. javascript满天小星星
  13. 【精美后台管理系统模版->UI界面欣赏】
  14. Understanding the Users and Videos by Mining a Novel Danmu Dataset
  15. 关于mac上如何U盘
  16. ViewPager2
  17. Java技能树-RE-正则应用-目录
  18. Android 监听来电广播
  19. 小米4c信号显示无服务器,小米4c网速慢解决方法(小米4c卡顿严重)
  20. python技术线上培训

热门文章

  1. 前端解读面向切面编程(AOP)
  2. 在 HTML 中引入 vue.js 写页面
  3. 第四章 生命周期函数--35 vue-resource发起get、post、jsonp请求
  4. python基础知识 - Day4
  5. 深入理解softmax函数
  6. 【second】Flatten Binary Tree to Linked List
  7. mysql order by int_mysql order by是怎么工作的?
  8. 用python自制背单词程序_c++自制背单词应用
  9. linux算法平台,Linux实时调度算法与测试平台的研究与实现
  10. linux vim 执行shell命令行,Linux中vim和shell