• 数据结构学习系列之线性表(四)


    前言

    使用没有指针的语言模拟实现数据结构,会碰到一些莫名奇妙的问题

    单向循环链表

    之前学习的链表都是单向且最后一个节点指向空节点,如果最后一个节点指向头节点,这样就形成了一个环,名字叫单向循环列表,简称循环列表

    源码(JS模拟实现)

    包含了头指针以及尾指针的实现

    /**
     * @desc 循环链表
     *
     * @author WadeYu
     * @date 2015-08-15
     * @copyright by WadeYu
     */
    var Node = function(data){
        this.data = data;
        this.next = null;
    };
    
    var ListInit = function(ptr){
        ptr.next = ptr;
    };
    var ListLength = function(ptr,bTail){
        var len = 0;
        var head = bTail ? ptr.next : ptr;
        var curr = head.next;
        while(curr != head){
            len++;
            curr = curr.next;
        }
        return len;
    };
    var ListClear = function(ptr){
        ptr.next = ptr;
    };
    var ListInsert = function(ptr,i,node,bTail){
        i = i - 1;
        var len = ListLength(ptr,bTail);
        if((i < 0) || (i > len)){
            return false;
        }
        var pos = 0;
        var curr = bTail ? ptr.next : ptr;
        while(true){
            if(pos == i){
                break;
            }
            curr = curr.next;
            pos++;
        }
        var tmp = curr.next;
        curr.next = node;
        node.next = tmp;
        if(bTail && (pos == len)){
            ptr = node;
        }
        return ptr; //JS变量赋值只在可见作用域范围才生效,因此这里需要返回
    };
    var ListDelete = function(ptr,i,bTail){
        var len = ListLength(ptr,bTail);
        if((i < 1)|| (i > len)){
            return false;
        }
        var curr = bTail ? ptr.next : ptr;
        var pos = 0;
        while(true){
            if(pos == (i-1)){
                break;
            }
            curr = curr.next;
            pos++;
        }
        var tmp = curr.next;
        curr.next = tmp.next;
        tmp = null;
        if(bTail && (i == len)){
            ptr = curr;
        }
        return ptr;
    };
    var GetElem = function(ptr,i,bTail){
        if((i < 1) || (i > ListLength(ptr,bTail))){
            return false;
        }
        var curr = bTail ? ptr.next : ptr;
        var pos = 0;
        while(true){
            if(pos == i){
                break;
            }
            curr = curr.next;
            pos++;
        }
        return curr;
    };
    var Locate = function(ptr,node,bTail){
        var pos = 0;
        if(ListLength(ptr,bTail) < 1){
            return -1;
        }
        var curr = bTail ? ptr.next.next : ptr.next;
        var head = bTail ? ptr.next : ptr;
        while( (curr != node) && (curr != head)){
            pos++;
            curr = curr.next;
        }
        if(curr == head){
            return -1;
        }
        return pos;
    };
    var ListEmpty = function(ptr){
        return ptr.next == ptr;
    };
    
    var print = function(ptr,bTail){
        var head = bTail ? ptr.next : ptr;
        var curr = bTail ? ptr.next.next : ptr.next;
        var a = [];
        while(curr != head){
            a.push(curr.data);
            curr = curr.next;
        }
        console.log(a.join(','));
    };
    
    var init = function(len,bTail){
        var cl = new Node(0);
        ListInit(cl);
        for(var i = 1; i <= len; i++){
           var tmp = ListInsert(cl,i,new Node(i),bTail);
           cl = tmp ? tmp : cl;
        }
        return cl;
    }
    
    var ListTailMerge = function(ptr1,ptr2){
        if(ListEmpty(ptr2)){
            return false;
        }
        var tmp = ptr1.next;
        ptr1.next = ptr2.next.next;
        ptr2.next = tmp;
        return ptr2;
    };
    

      

    应用---约瑟夫环

    简介:一组数字,从左数到右,删除第N个数字,然后从新开始数,如此循环,直到剩下最后一个数字

    分析:这个过程可以用循环链表模拟

    var cl = init(50);
    print(cl);
    var num = 0;
    var reject = 2;
    var head = cl;
    var curr = cl.next;
    var tmp = {};
    while(ListLength(cl) > 1){
        if(curr != head){
            num++;
        }
        if( num == reject ){
            tmp = curr.next;
            if(tmp != head){
                num = 0;
                curr.next = tmp.next;
            }
        }
        curr = curr.next;
    }
    console.log("Last Number is : "+cl.next.data);
    

      

    后记

    1.因为JS是没有指针的弱类型语言,赋值操作只在可见作用范围内生效

    2.JS模拟数据结构,最好通过OO的形式实现,OO可以共享数据,使用面向过程方式实现不方便

    作者:WadeYu
    出处:http://www.cnblogs.com/wadeyu/
    本文版权归本人和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    It's Android Time:程序员创富有道
    《linux核心应用命令速查》连载十五:chkconfig:设置系统的各种服务
    IBM资深副总裁 推荐《营销2.0最佳实践:网络营销时代的ANGELS制胜法则》
    《linux核心应用命令速查》连载十二:top:显示进程
    《linux核心应用命令速查》连载九:crontab:设置计时器
    软件测试管理是什么?
    Sandy Carter,IBM副总裁 推荐《营销2.0最佳实践:网络营销时代的ANGELS制胜法则》
    BizTalk Server 2010 使用 WCF Service [ 下篇 ]
    BizTalk请求JAVA的Web Service报错
    ExtJS 4.0 beta 3的更新说明
  • 原文地址:https://www.cnblogs.com/wadeyu/p/4734878.html
Copyright © 2020-2023  润新知