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 布尔型分析
Dec 22 Javascript
Jquery 点击按钮显示和隐藏层的代码
Jul 25 Javascript
JS继承用法实例分析
Feb 05 Javascript
jQuery获得包含margin的outerWidth和outerHeight的方法
Mar 25 Javascript
javascript检测两个数组是否相似
May 19 Javascript
JS实现带有3D立体感的银灰色竖排折叠菜单代码
Oct 20 Javascript
JavaScript中的对象继承关系
Aug 01 Javascript
老生常谈原生JS执行环境与作用域
Nov 22 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
Mar 08 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
Js 利用正则表达式和replace函数获取string中所有被匹配到的文本(推荐)
Oct 28 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
Nov 14 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
如何使用PHP获取指定日期所在月的开始日期与结束日期
2013/08/01 PHP
php密码生成类实例
2014/09/24 PHP
用php代码限制国内IP访问我们网站
2015/09/26 PHP
Laravel框架执行原生SQL语句及使用paginate分页的方法
2018/08/17 PHP
让 JavaScript 轻松支持函数重载 (Part 2 - 实现)
2009/08/04 Javascript
jquery的ajax简单结构示例代码
2014/02/17 Javascript
javascript模拟订火车票和退票示例
2014/04/24 Javascript
jquery zTree异步加载、模糊搜索简单实例分享
2016/03/24 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
AngularJS  $on、$emit和$broadcast的使用
2016/09/05 Javascript
ionic中列表项增加和删除的实现方法
2017/01/22 Javascript
BootStrap表单时间选择器详解
2017/05/09 Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
2018/04/17 Javascript
JavaScript检查数据中是否存在相同的元素(两种方法)
2018/10/07 Javascript
Vue源码学习之关于对Array的数据侦听实现
2019/04/23 Javascript
使用vuex解决刷新页面state数据消失的问题记录
2019/05/08 Javascript
jQuery 筛选器简单操作示例
2019/10/02 jQuery
js模拟实现百度搜索
2020/06/28 Javascript
js实现盒子拖拽动画效果
2020/08/09 Javascript
Python的加密模块md5、sha、crypt使用实例
2014/09/28 Python
python django 访问静态文件出现404或500错误
2017/01/20 Python
浅谈python之高阶函数和匿名函数
2019/03/21 Python
Python 中包/模块的 `import` 操作代码
2019/04/22 Python
Python 利用Entrez库筛选下载PubMed文献摘要的示例
2020/11/24 Python
Python中生成ndarray实例讲解
2021/02/22 Python
HTML5 在canvas中绘制矩形附效果图
2014/06/23 HTML / CSS
H5最强接口之canvas实现动态图形功能
2019/05/31 HTML / CSS
Vrbo英国:预订度假屋
2020/08/19 全球购物
Linux上比较文件的命令都有哪些
2012/02/24 面试题
华为python面试题
2016/05/03 面试题
学期研究性学习个人的自我评价
2014/01/09 职场文书
爱祖国演讲稿
2014/05/04 职场文书
出差报告范文
2014/11/06 职场文书
金榜题名主持词
2015/07/02 职场文书
Mysql实现简易版搜索引擎的示例代码
2021/08/30 MySQL
《原神》新角色演示“神里绫人:林隐泓洄” 宠妹狂魔
2022/04/03 其他游戏