K:线性表的实现—链表
单链表的概念:
采用链式存储方式存储的线性表称之为链表,链表中每个节点包含存放数据元素的值的数据域和存放指向逻辑上相邻节点的指针域。若一个节点中只包含一个指针域,则称此链表为单链表。
单链表的特点:
1. 单链表是通过指向后继节点的指针把它的一串节点连接成一个链
2. 以线性表这种第一个数据元素的存储地址作为线性表的起始地址,称做线性表的头指针。一个单链表就是由他的头指针head来唯一的标识他。
3. 单链表中的最后一个节点(尾节点)没有后继,所以它的指针域的值用空指针null。
4. 为了操作方便,在第一个存入数据的节点之前加入一个虚节点称为“头节点”,头结点的数据域一般不存放具体的值,指针域存放指向第一个节点(首节点)的指针,指向头节点的指针为单链表的头指针。
5. 若线性表为空表,则头指针的指针域为空
单链表的节点类的相关代码(java):
class Node<T>
{
public T data;//用于存储相关的数据域
public Node<T> next;//用于存储相关的指针域
public Node()
{
this(null,null);
}
public Node(T data)
{
this(data,null);
}
public Node(T data,Node next)
{
this.data=data;
this.next=next;
}
}
单链表实现的相关代码(java):
public class LinkedList<T> implements List<T>
{
public Node head;//用于存储头指针
public LinkedList()
{
head=new Node();
}
public void clear()//清空,时间复杂度为O(1)
{
head=new Node();
}
public boolean isEmpty()//判空操作,时间复杂度为O(1)
{
return head.next==null;
}
public int length()//求长度
{
int k=0;
Node p=head.next;
while(p!=null)
{
k++;
p=p.next;
}
return k;
}
public T get(int i)throws Exception//按位查找,其时间复杂度为O(n)
{
int j=0;
Node p=head.next;
while(j<i&&p!=null)
{
j++;
p=p.next;
}
if(j>i||p==null)
{
throw new Exception(“查找的位置不存在”);
}
return p.data;
}
public int indexOf(T x)//按值查找,其时间复杂度为O(n)
{
int j=0;
Node p=head.next;
while(p!=null&&!p.data.equals(x))
{
j++;
p=p.next;
}
if(p==null)
return -1;
else
return j;
}
public void insert(int i,T x)throws Exception//插入操作,其时间复杂度为O(n)
{
int j=-1;
Node p=head;
while(j<i-1&&p!=null)//用于找到插入位置的前一个节点
{
j++;
p=p.next;
}
if(i-1<j||p==null)
{
throw new Exception(“插入的位置不合法”);
}
Node s=new Node(x);
s.next=p.next;
p.next=s;
}
public void remove(int i)throws Exception//删除操作,时间复杂度为O(n)
{
int j=-1;
Node p=head;
while(j<i-1&&p.next!=null)
{
j++;
p=p.next;
}
if(j>i-1||p.next!=null)
{
throw new Exception(“删除的位置不合法”);
}
p.next=p.next.next;
}
}
ps:对于单链表的删除操作而言,其必须要找到进行删除的节点的前继节点,之后才能进行删除。删除某个特定节点的另一个思路是,将下一个节点的数据域的值赋值给本节点的数据域,之后,删除通过该特定节点,去删除下一个节点。这样做的局限在于,无法删除单链表中的最后一个节点。
其它链表:
除了单链表之外,还有单链表的改进和结构的调整,常见的有循环链表和双向链表以及双向循环链表。
ps:对于“链表”该名词,有两种含义,一种是指单链表,一种是指各种形式的链式存储结构。为此,“链表”的具体含义应该取决于上下文。
单向循环链表:
循环链表也称为环形链表,其结构和单链表相似,只是将单链表的首尾相连,即将单链表的最后一个节点的后继指针指向第一个节点,从而构成一个环形链表
在循环链表中,每一个节点都有后继,所以,从循环链表的任意一个节点出发都可以访问到单链表中的所有节点。
对于单链表和循环链表,其API的实现上大多数没有什么区别,仅有的区别在于判断是否为最后一个节点的时候是否为头结点,而不是单链表实现上的最后一个节点为null。
在实现循环链表时,既可以用头指针来标识循环链表,也可以用尾指针(所谓的尾指针,指的是指向末尾节点的指针)来标识,也可以头尾指针都用。若仅用头指针标识循环链表,则访问第一个节点的时间复杂度为O(1),但是访问最后一个节点的时间复杂度为O(n);若仅用尾指针标识的循环链表,则不论是访问第一个节点还是访问最后一个节点,其时间复杂度为O(1),所以,在实际操作中,使用尾指针来标识循环链表,这样会简化某些操作
双向链表
在单链表中的节点仅仅包含指向其后继节点的指针,所以要查找一个指定节点的后继节点,只要顺着其后继指针即可找到,其时间复杂度为O(1),但是,若其要找到某个指定节点的前驱节点,则其需要从单链表的表头开始顺着链依次进行查找,其时间复杂度为O(n),为了解决这个问题,让每一个节点都有两个指针域,一个指向前驱节点,一个指向后继节点,此种链表就称为双向链表。
双向循环链表
将双向链表的首尾进行相连即可构成双向循环链表
双向链表的节点插入及删除操作图
插入:
删除:
K:线性表的实现—链表的更多相关文章
- 玩转C线性表和单向链表之Linux双向链表优化
前言: 这次介绍基本数据结构的线性表和链表,并用C语言进行编写:建议最开始学数据结构时,用C语言:像栈和队列都可以用这两种数据结构来实现. 一.线性表基本介绍 1 概念: 线性表也就是关系户中最简单的 ...
- c/c++ 线性表之单向链表
c/c++ 线性表之单向链表 线性表之单向链表 不是存放在连续的内存空间,链表中的每个节点的next都指向下一个节点,最后一个节点的下一个节点是NULL. 真实的第一个节点是头节点,头节点不存放数据, ...
- 线性表之单链表C++实现
线性表之单链表 一.头文件:LinkedList.h //单链表是用一组任意的存储单元存放线性表的元素,这组单元可以是连续的也可以是不连续的,甚至可以是零散分布在内存中的任意位置. //单链表头文件 ...
- [数据结构 - 第3章] 线性表之单链表(C++实现)
一.类定义 单链表类的定义如下: #ifndef SIGNALLIST_H #define SIGNALLIST_H typedef int ElemType; /* "ElemType类型 ...
- [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)
[数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构) C#中的链表(源码) 可空类 ...
- 【Java】 大话数据结构(2) 线性表之单链表
本文根据<大话数据结构>一书,实现了Java版的单链表. 每个结点中只包含一个指针域的链表,称为单链表. 单链表的结构如图所示: 单链表与顺序存储结构的对比: 实现程序: package ...
- 续上文----线性表之单链表(C实现)
本文绪上文线性表之顺序表(C实现) 本文将继续使用单链表实现线性表的另外一种存储结构.这种使用链表实现的存储结构在内存中是不连续的. C实现代码如下: #include<stdio.h> ...
- 线性表 (单链表、循环链表-python实现)
一.线性表 线性表的定义: 线性表是具有相同数据类型的有限数据的序列. 线性表的特点: 出了第一个元素外,每个元素有且仅有一个直接前驱,除最后一个元素外有且只有一个后继. 线性表是一种逻辑结构,表示元 ...
- 数组线性表ArrayList 和链表类LinkedList
数组线性表类ArrayList 和链表类LinkedList 是实现List接口的两个具体类.ArrayList 数组储存元素,这个数组是动态创建的.如果元素个数超过了数组的容量,就创建一个更大的新数 ...
随机推荐
- 使用Bitbucket Pipeline进行.Net Core项目的自动构建、测试和部署
1. 引言 首先,Bitbucket提供支持Mercurial和Git版本控制系统的网络托管服务.简单来说,它类似于GitHub,不同之处在于它支持个人免费创建私有项目仓库.除此之外,Bitbucke ...
- Git基本使用命令(windows)
1. 记住一个名词repository版本库 =======================基本操作======================== git init 在需要的地方建立一个版本库(也 ...
- C#设计模式之二十策略模式(Stragety Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第七个模式,该模式是[策略模式],英文名称是:Stragety Pattern.在现实生活中,策略模式的例子也非常常见,例如,在一个 ...
- Nginx限速模块初探
Nginx限速模块分为哪几种?按请求速率限速的burst和nodelay参数是什么意思?漏桶算法和令牌桶算法究竟有什么不同?本文将带你一探究竟.我们会通过一些简单的示例展示Nginx限速模块是如何工作 ...
- 电脑创建WIFI/无线热点之后, 手机QQ能上浏览器不能上网
这个完全是个人经验,绝对原创,请尊重博主原创权,转载请注明转于此博客. 问题如题,大家电脑创建无线热点之后, 有的人手机会出现QQ,微信能上网, 但是浏览器或者基于浏览器的那些比如应用商店不能上网, ...
- Java-----关于线程池的使用
关于线程的相关概念不在此阐述,请百度或谷歌之 对于学习线程来说,我认为从代码开始学习比较好,前提是有一定的技术的积累,否则请关闭不用再看了~ 线程池四种实现方式. ①可缓存线程池,如果线程池长度超过处 ...
- 》》QQ-注册
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python爬虫(二十一)_Selenium与PhantomJS
本章将介绍使用Selenium和PhantomJS两种工具用来加载动态数据,更多内容请参考:Python学习指南 Selenium Selenium是一个Web的自动化测试工具,最初是为网站自动化测试 ...
- Oracle改动字段类型和长度
Oracle改动字段名 alter table 表名 rename column 旧字段名 to 新字段名 Oracle改动字段类型和长度 alter table 表名 modify 字段名 数据类型 ...
- 为Android Studio设置HTTP代理
大陆的墙非常厚非常高.初次安装Android Studio下载SDK等必然失败,设置代理方法例如以下: 1. 到android studio安装文件夹,打开bin文件夹.编辑idea.properti ...