详谈双向链表的实现与简单操作

1.单链表的一个优点是结构简单,但是它也有一个缺点,即在单链表中只能通过一个结点的引用访问其后续结点,而无法直接访问其前驱结点,要在单链表中找到某个结点的前驱结点,必须从链表的首结点出发依次向后寻找,但是需要Ο (n)时间。为此我们可以扩展单链表的结点结构,使得通过一个结点的引用,不但能够访问其后续结点,也可以方便的访问其前驱结点。扩展单链表结点结构的方法是,在单链表结点结构中新增加一个域,该域用于指向结点的直接前驱结点。扩展后的结点结构是构成双向链表的结点结构。在双向链表中进行查找与在单链表中类似,只不过在双向链表中查找操作可以从链表的首结点开始,也可以从尾结点开始,但是需要的时间和在单链表中一样。

  单链表的插入操作,除了首结点之外必须在某个结点的后面进行,而在双向链表中,在一个已知的结点之前或之后都可以。

1)s.prev
= p.prev;

2) p.prev.next = s;

3) s.next = p;

4) p.prev = s;

单链表的删除操作,除了首结点之外必须在知道待删结点的前驱结点的基础上才能进行,而在双向链表中在已知某个结点引用的前提下,可以完成该结点自身的删除。

  p.prev.next = p.next;

  p.next.prev = p.prev;

  在具有头尾结点的双向链表中插入和删除结点,无论插入和删除的结点位置在何处,因为首尾结点的存在,插入、删除操作都可以被归结为上图介绍的在双向链表某个中间结点的插入和删除;并且因为首尾结点的存在,整个链表永远不会为空,因此在插入和删除结点之后,也不用考虑链表由空变为非空或由非空变为空的情况下 head 和 tail 的指向问题;从而简化了程序。

  双向链表的缺点是每次插入或删除一个结点的时候,要处理四个链结点的引用,而不是两个;两个连接前一个一个链结点,两个连接后一个链结点。当然由于多了两个引用,链结点的占用空间也大了一些。

<strong>public class DoubleLink {
 public Link first;
 public Link last;
 public DoubleLink() { // 构造器初始化
  this.last = null;
  this.first = null;
 }
 public boolean isEmpty() { // 判断是否为空
  return first == null;
 }
 public void insertFirst(int data) { // 将元素插入链表头
  Link link = new Link(data);
  if (isEmpty())
   last = link; // 如果为空,last需要改变
  else
   first.prev = link;
  link.next = first;
  first = link;
 }
 public void insertLast(int data) { // 将元素插入链表尾
  Link link = new Link(data);
  if (isEmpty())
   last = link;
  else
   last.prev = link;
  link.prev = last;
  last = link;
 }
 public boolean insertAfter(int key, int idata) { // 在某元素后插入
  Link current = first;
  while (current.data != key) {
   current = current.next;
  }
  Link link = new Link(idata);
  if (current == last) {
   link.next = null;
   last = link;
  } else {
   link.next = current.next;
   current.next.prev = link;
  }
  link.prev = current;
  current.next = link;
  return true;
 }
 public Link deleteKey(int key) { // 删除某项元素
  Link current = first;
  while (current.data != key) {
   current = current.next;
  }
  first = current.next;
  if (current == last)
   last = current.prev;
  else
   current.next.prev = current.prev;
  return current;
 }
 public Link deleteFirst() { // 删除表开头的元素
  Link temp = first;
  if (first.next == null)
   last = null;
  else
   first.next.prev = null; // first结点的next字段引用的链结点的prev字段
  first = first.next;
  return temp;
 }
 public Link deleteLast() { // 删除表末尾的元素
  Link temp = last;
  if (first.next == null)
   first = null;
  else
   last.prev.next = null;
  last = last.prev;
  return temp;
 }
 public void showFirst() {// 前向展示
  Link current = last;
  while (current != null) {
   current.show();
   current = current.prev;
  }
 }
 public void showLast() {// 后向展示
  Link current = first;
  while (current != null) {
   current.show();
   current = current.next;
  }
 }
 public static void main(String[] args) {
  DoubleLink dlink = new DoubleLink();
  dlink.insertFirst(1);
  dlink.insertFirst(3);
  dlink.insertFirst(2);
  dlink.insertAfter(2, 4);
  dlink.showFirst();
 }
}
class Link {
 public int data; // 存放的数据
 public Link prev;// 对前一项的引用,直接前驱
 public Link next;// 对后一项的引用,直接后继
 public Link(int data) {
  this.data = data;
 }
 public void show() {
  System.out.println(data + " ");
 }
}</strong>

时间: 2024-10-10 20:40:29

详谈双向链表的实现与简单操作的相关文章

ORACLE的安装与网页版创建表空间的简单操作以及PLsql的简单操作

1.oracle的安装: 安装简单易学,在这里不做解释.下载看装包后耐心等待,注意安装目录不要有中文字符,尽量按照指定目录进行安装.安装完成后会占用有大约5g的内存. 如果要卸载oracle,需要用其自带的卸载工具进行卸载[universal installer],然后删除注册表项,删除环境变量,删除目录并且重新启动计算机. 2.在网页版进行创建表空间: 进入网页版: 在电脑的服务中我们可以看到一共有7个oracle的服务项目,其中只有三个是正在启动中.这三项中,只有当OracleDBConso

简单操作只需10秒破解PDF加密文件

简单操作只需10秒破解PDF加密文件 [尊重原创,转载请注明出处]http://blog.csdn.net/guyuealian/article/details/51345950 如何破解PDF加密文件,如何破解PDF密码呢,破解加密的PDF文件? 从网上下载的PDF文件,由于版权的问题,作者经常会加密禁止读者复制修改等权限,如下面的PDF文档,用Adobe pdf Reader打开时,会显示"已加密"的字样,虽然可以阅读,但不能修改和标记. 为了解决这个问题,可以采用绕过破解密码这一

C++ 文件的简单操作

=================================================================== 编写程序时,很多时候都要对文件进行操作,比如从文件中读取数据,通过程序将一些数据保存到文件中等等.. 以下是c++对文件的一些简单操作. =================================================================== 一.文件输出 要将程序中的数据输出到文件中,一般需要以下5个步骤: ① 包含fstream

mysql数据库很简单操作

进入linux系统 root   >/usr/bin/mysql -u root mysql>show databases;                    #查看数据库 mysql>use  testtable;                        #testtable 为所要查看的库,应用数据库 mysql>show tables;                          #查看所有表 mysql>desc abc_table          

ftp简单操作及解说

一.实验拓扑 服务器 ------------------------客户机 二.实验条件 试验机在同一个网段,可以互相ping通. 确定装在了ftp软件包. 三.实验一: 匿名用户与本地用户都可以登录 匿名用户登录到/var/ftp,只能下载不能上传 本地用户登录到本地用户的家目录,可以上传和下载 实验步骤; [[email protected] ~]# rpm -q vsftp              //检测是否安装软件 package vsftp is not installed   

nfs简单操作及解说

NFS的实验报告 一.实验拓扑: 服务器 ----------      客户机 二.实验条件: 服务器的ip:192.168.4.5/24 客户机的ip:192.168.4.200 要确定机器有安装nfs包跟RPC软件包. 三.实验要求: 将/root 共享给192.168.4.200 可写,同步,允许客户机以root权限访问 NFS 服务端操作: 修改配置: [[email protected] ~]# vim /etc/exports    //修改配置的地址 [[email protec

PgSQL简单操作

********************************************** *基本操作 ********************************************** 数据库操作 $ psql test $ psql -h localhost -U username -W newpwd -p 5432 test =# create database mail_db; =# create database mail_db owner sunny; =# drop d

JS的简单操作和表单以及事件

HTML:主要用于往页面上放置所需要的控件. CSS:主要用来控制页面以及上面控件的样式. JS:主要用来控制页面上的特效以及数据交互. JS也分为顺序,条件(IF()... ELSE()),循环(FOR())三种语句,与C#基本一致. JS定义变量统一用var,定义数组不固定长度和类型,类似C#中的集合. JS的简单操作: DOM操作: 一.window: 1.window.onload 页面打开完再执行后面的操作 2.window.open(1,2,3,4) - 打开新页面, 1 - 打开页

Java时间简单操作

使用java操作时间感觉真真蛋疼,还是我大C#舒服,一个DateTime全部搞定 这里的Date指的是java.util.Date 获取当前时间: // 创建一个当前时间的Date对象 Date time = new Date(); 蛋疼的地方,对时间增.减操作: // 使用Calendar类对时间增.减操作 Calendar c = Calendar.getInstance();// 获得一个Calendar实例,该类是抽象类所以不可以使用new构造方法 // 使用setTime方法创建一个时