javascript数据结构之双链表插入排序实例详解


Posted in Javascript onNovember 25, 2015

本文实例讲述了javascript数据结构之双链表插入排序实现方法。分享给大家供大家参考,具体如下:

数组存储前提下,插入排序算法,在最坏情况下,前面的元素需要不断向后移,以便在插入点留出空位,让目标元素插入。

换成链表时,显然无需做这种大量移动,根据每个节点的前驱节点“指针”,向前找到插入点后,直接把目标值从原链表上摘下,然后在插入点把链表断成二截,然后跟目标点重新接起来即可。

<!doctype html>
<html>
<head>
  <title>双链表-插入排序</title>
  <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
</head>
<script type="text/javascript">
  //节点类
  var Node = function (pData) {
    this.next = null; //后继“指针”
    this.prev = null; //前驱"指针"
    this.data = pData;
  }
  //单链表(约定:头节点不放内容,当哨兵位,有效元素从头节点后的第1个元素开始)
  var DbLinkList = function () {
    this.head = new Node(null); //头节点   
    //插入新元素
    this.insert = function (pNodeValue) {
      var newNode = new Node(pNodeValue);
      //如果只有头节点
      if (this.head.next == null) {
        this.head.next = newNode;
        newNode.prev = this.head;
        return;
      }
      //否则遍历找到尾节点
      var p = this.head;
      while (p.next != null) {
        p = p.next;
      }
      p.next = newNode;
      newNode.prev = p;
    }
    //获取第n个元素的数据值
    this.getData = function (index) {
      if (index < 1 || index > this.size) {
        return null;
      }
      var p = this.head;
      var i = 1;
      while (p.next != null && i <= index) {
        p = p.next;
        i += 1;
      }
      return p.data;
    }
    //取尾节点
    this.getTail = function () {
      if (this.head.next == null) {
        return null;
      }
      var p = this.head.next;
      while (p.next != null) {
        p = p.next;
      }
      return p;
    }
    //删除指定位置的元素
    this.removeAt = function (index) {
      if (index < 1 || index > this.size) {
        return null;
      }
      var p = this.head;
      var i = 1;
      //从头开始遍历,找到index位置的前一个元素
      while (p.next != null && i < index) {
        p = p.next;
        i += 1;
      }
      p.next = p.next.next; //修改index位置前一个元素的后继指针
      p.next.prev = p;
      return p.data; //返回删除元素的值    
    }
    //打印所有元素
    this.print = function () {
      document.write("<br/>");
      if (this.head.next == null) {
        return;
      }
      var p = this.head.next;
      while (p.next != null) {
        document.write(p.data + " ");
        p = p.next;
      }
      document.write(p.data + " "); //最后一个元素,需要单独打印
      document.write("<br/>");
    }
    //从后打印所有元素
    this.printFromBack = function () {
      document.write("该链表共有" + this.size + "个元素,从后向前分别为:<br/>");
      var tail = this.getTail();
      var p = tail;
      if (p == null) {
        return;
      }
      while (p.prev != null) {
        document.write(p.data + " ");
        p = p.prev;
      }
      document.write("<br/>");
    }
    //插入排序
    this.insertSort = function () {
      if (this.head.next == null || this.head.next.next == null) {
        return;
      }
      var p = this.head.next;
      while (true) {
        if (p == null) {
          return;
        }
        var t = p.prev;
        //向前查找p之前的插入点
        while (t.prev != null && t.data > p.data) {
          t = t.prev;
        }
        //如果插入点就是p的前驱节点,不用调整,
        //忽略,直接进入下一轮
        if (t.next == p) {
          p = p.next;
          continue;
        }
        //将p的后续节点先保护起来,以便下一轮循环时确定起始位置
        var x = p.next;
        //将p从链表上摘下
        if (p.next != null) {
          p.next.prev = p.prev;
        }
        p.prev.next = p.next;
        //p插入到t之后
        t.next.prev = p;
        p.next = t.next;
        t.next = p;
        p.prev = t;
        this.print(); //打印输出,调试用  
        //重新将p定位到下一轮循环的"正确"起始节点
        p = x;
      }
    }
  }
  var linkTest = new DbLinkList();
  linkTest.insert(10);
  linkTest.insert(9);
  linkTest.insert(8);
  linkTest.insert(7);
  linkTest.insert(6);
  linkTest.insert(5);
  linkTest.insert(4);
  linkTest.insert(3);
  linkTest.insert(2);
  linkTest.insert(1);
  document.write("--排序前---<br/>")
  linkTest.print();
  linkTest.insertSort();
  document.write("<br/>--排序后---<br/>")
  linkTest.print();
</script>
</html>

运行结果如下:

--排序前---

10 9 8 7 6 5 4 3 2 1 

9 10 8 7 6 5 4 3 2 1 

8 9 10 7 6 5 4 3 2 1 

7 8 9 10 6 5 4 3 2 1 

6 7 8 9 10 5 4 3 2 1 

5 6 7 8 9 10 4 3 2 1 

4 5 6 7 8 9 10 3 2 1 

3 4 5 6 7 8 9 10 2 1 

2 3 4 5 6 7 8 9 10 1 

1 2 3 4 5 6 7 8 9 10 

--排序后---

1 2 3 4 5 6 7 8 9 10

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript中拼接HTML字符串的最快、最好的方法
Jun 07 Javascript
JS小游戏之象棋暗棋源码详解
Sep 25 Javascript
js实现同一页面多个不同运动效果的方法
Apr 10 Javascript
jQuery插件jPaginate实现无刷新分页
May 04 Javascript
Extjs实现下拉菜单效果
Apr 01 Javascript
Bootstrap基本组件学习笔记之导航(10)
Dec 07 Javascript
Javascript同时声明一连串(多个)变量的方法
Jan 23 Javascript
解决vue.js在编写过程中出现空格不规范报错的问题
Sep 20 Javascript
JavaScript显式数据类型转换详解
Mar 18 Javascript
vue + typescript + video.js实现 流媒体播放 视频监控功能
Jul 07 Javascript
微信小程序wx.navigateTo中events属性实现页面间通信传值,数据同步
Jul 13 Javascript
vuex实现购物车功能
Jun 28 Javascript
js获取图片宽高的方法
Nov 25 #Javascript
javascript数据结构之二叉搜索树实现方法
Nov 25 #Javascript
javascript常用经典算法实例详解
Nov 25 #Javascript
javascript实现很浪漫的气泡冒出特效
Sep 05 #Javascript
jQuery插件jquery-barcode实现条码打印的方法
Nov 25 #Javascript
JavaScript编写简单的计算器
Nov 25 #Javascript
HTML5 Shiv完美解决IE(IE6/IE7/IE8)不兼容HTML5标签的方法
Nov 25 #Javascript
You might like
Excel数据导入Mysql数据库的实现代码
2008/06/05 PHP
php URL编码解码函数代码
2009/03/10 PHP
解析php常用image图像函数集
2013/06/24 PHP
php cookie名使用点号(句号)会被转换
2014/10/23 PHP
PHP读取CSV大文件导入数据库的实例
2017/07/24 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
PHP echo()函数讲解
2019/02/15 PHP
PHP isset()及empty()用法区别详解
2020/08/29 PHP
jQuery 1.5最新版本的改进细节分析
2011/01/19 Javascript
理解javascript闭包
2015/12/15 Javascript
微信小程序商城项目之侧栏分类效果(1)
2017/04/17 Javascript
jQuery插件FusionCharts绘制的2D条状图效果【附demo源码】
2017/05/13 jQuery
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
JavaScript中常见内置函数用法示例
2018/05/14 Javascript
Layui 设置select下拉框自动选中某项的方法
2018/08/14 Javascript
webpack的CSS加载器的使用
2018/09/11 Javascript
Javascript和jquery在selenium的使用过程
2019/10/31 jQuery
Vue中正确使用Element-UI组件的方法实例
2020/10/13 Javascript
vue的hash值原理也是table切换实例代码
2020/12/14 Vue.js
[07:25]DOTA2-DPC中国联赛2月5日Recap集锦
2021/03/11 DOTA
详解Django通用视图中的函数包装
2015/07/21 Python
python requests post多层字典的方法
2018/12/27 Python
Python Django 页面上展示固定的页码数实现代码
2019/08/21 Python
基于python实现雪花算法过程详解
2019/11/16 Python
python批量修改文件名的示例
2020/09/27 Python
高级护理专业大学生求职信
2013/10/24 职场文书
职专应届生求职信
2013/11/16 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
创先争优公开承诺书
2014/08/30 职场文书
2014年群众路线教育实践活动整改措施
2014/09/24 职场文书
个人租房协议书样本
2014/10/01 职场文书
文员岗位职责
2015/02/04 职场文书
2015年保洁工作总结范文
2015/04/28 职场文书
Python中递归以及递归遍历目录详解
2021/10/24 Python
Oracle使用别名的好处
2022/04/19 Oracle
CSS中理解层叠性及权重如何分配
2022/12/24 HTML / CSS