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 相关文章推荐
jscript之List Excel Color Values
Jun 13 Javascript
编写高性能的JavaScript 脚本的加载与执行
Apr 19 Javascript
JavaScript中清空数组的三种方法分享
Apr 07 Javascript
页面只能打开一次Cooike如何实现
Dec 04 Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
Nov 18 Javascript
用js控制组织结构图可以任意拖拽到指定位置
Jan 17 Javascript
详解jQuery UI库中文本输入自动补全功能的用法
Apr 23 Javascript
vue中渐进过渡效果实现
Oct 27 Javascript
原生js实现弹出层效果
Jan 20 Javascript
vue双向绑定简要分析
Mar 23 Javascript
JavaScript实现移动端轮播效果
Jun 06 Javascript
elementUI多选框反选的实现代码
Apr 03 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/11/25 PHP
php中session退出登陆问题
2014/02/27 PHP
PHP实现补齐关闭的HTML标签
2016/03/22 PHP
Laravel中错误与异常处理的用法示例
2018/09/16 PHP
Jquery 实现table样式的设定
2015/01/28 Javascript
JavaScript常用脚本汇总(二)
2015/03/04 Javascript
jQuery中deferred对象使用方法详解
2016/07/14 Javascript
实例解析angularjs的filter过滤器
2016/12/14 Javascript
node.js中debug模块的简单介绍与使用
2017/04/25 Javascript
深入理解vue-router之keep-alive
2017/08/31 Javascript
网页爬虫之cookie自动获取及过期自动更新的实现方法
2018/03/06 Javascript
使用vue-cli导入Element UI组件的方法
2018/05/16 Javascript
使用VUE+iView+.Net Core上传图片的方法示例
2019/01/04 Javascript
vue在自定义组件中使用v-model进行数据绑定的方法
2019/03/25 Javascript
Vue Render函数创建DOM节点代码实例
2020/07/08 Javascript
[31:55]完美世界DOTA2联赛循环赛 IO vs GXR BO2第一场 11.04
2020/11/05 DOTA
Python标准库之多进程(multiprocessing包)介绍
2014/11/25 Python
python 读取摄像头数据并保存的实例
2018/08/03 Python
Python Pandas实现数据分组求平均值并填充nan的示例
2019/07/04 Python
适合Python初学者的一些编程技巧
2020/02/12 Python
Python3.x+pyqtgraph实现数据可视化教程
2020/03/14 Python
浅谈keras中Dropout在预测过程中是否仍要起作用
2020/07/09 Python
如何解决pycharm调试报错的问题
2020/08/06 Python
python中round函数保留两位小数的方法
2020/12/04 Python
关于h5中的fetch方法解读(小结)
2017/11/15 HTML / CSS
AutoShack.com加拿大:北美主要的汽车零部件零售商
2019/07/24 全球购物
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
物业管理公司实习生自我鉴定
2013/09/19 职场文书
财务与信息服务专业推荐信
2013/11/28 职场文书
外国人聘用意向书
2014/04/01 职场文书
三下乡个人总结
2015/03/04 职场文书
2015年底工作总结范文
2015/05/15 职场文书
比赛主持人开场白
2015/05/29 职场文书
名人传读书笔记
2015/06/26 职场文书
护士年终工作总结不会写?各科护士模板总结
2020/01/02 职场文书
Python Django获取URL中的数据详解
2021/11/01 Python