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操纵Cookie实现购物车程序
Feb 15 Javascript
javascript中call,apply,bind的用法对比分析
Feb 12 Javascript
JS区分浏览器页面是刷新还是关闭
Apr 17 Javascript
jQuery获取单击节点对象的方法
Jun 02 Javascript
Javascript 实现计算器时间功能详解及实例(二)
Jan 08 Javascript
Javascript DOM事件操作小结(监听鼠标点击、释放,悬停、离开等)
Jan 20 Javascript
bootstarp modal框居中显示的实现代码
Feb 18 Javascript
vue实现动态数据绑定
Apr 28 Javascript
JS中将多个逗号替换为一个逗号的实现代码
Jun 23 Javascript
原生JS实现日历组件的示例代码
Sep 22 Javascript
js限制输入框只能输入数字(onkeyup触发)
Sep 28 Javascript
微信小程序实现弹出层效果
May 26 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中文本数据翻页(留言本翻页)
2006/10/09 PHP
php下清空字符串中的HTML标签的代码
2010/09/06 PHP
关于PHP的相似度计算函数:levenshtein的使用介绍
2013/04/15 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
2014/06/12 PHP
PHP使用正则表达式获取微博中的话题和对象名
2015/07/18 PHP
使用WordPress发送电子邮件的相关PHP函数用法解析
2015/12/15 PHP
php UNIX时间戳用法详解
2017/02/16 PHP
laravel dingo API返回自定义错误信息的实例
2019/09/29 PHP
JS类库Bindows1.3中的内存释放方式分析
2007/03/08 Javascript
List Installed Software Features
2007/06/11 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
2013/01/16 Javascript
封装了jQuery的Ajax请求全局配置
2015/02/05 Javascript
jQuery formValidator表单验证
2016/01/07 Javascript
JS实现获取当前URL和来源URL的方法
2016/08/24 Javascript
Bootstrap Table的使用总结
2016/10/08 Javascript
利用jquery正则表达式在页面验证url网址输入是否正确
2017/04/04 jQuery
微信小程序之页面拦截器的示例代码
2017/09/07 Javascript
vue+element加入签名效果(移动端可用)
2019/06/17 Javascript
vue实现动态表格提交参数动态生成控件的操作
2020/11/09 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
[57:47]Fnatic vs Winstrike 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python中黄金分割法实现方法
2015/05/06 Python
Python使用Redis实现作业调度系统(超简单)
2016/03/22 Python
Python出现segfault错误解决方法
2016/04/16 Python
Python通过future处理并发问题
2017/10/17 Python
django 外键model的互相读取方法
2018/12/15 Python
安装2019Pycharm最新版本的教程详解
2019/10/22 Python
python模拟实现斗地主发牌
2020/01/07 Python
pytorch nn.Conv2d()中的padding以及输出大小方式
2020/01/10 Python
django 前端页面如何实现显示前N条数据
2020/03/16 Python
Python+unittest+DDT实现数据驱动测试
2020/11/30 Python
历史专业个人求职信范文
2013/12/07 职场文书
酒店中秋节活动方案
2014/01/31 职场文书
降消项目实施方案
2014/03/30 职场文书
放假通知怎么写
2015/08/18 职场文书
趣味运动会口号
2015/12/24 职场文书