JavaScript数据结构 (手打代码)

array:

数组创建:

var troop=new Array(6);                    //创建一个长度为6的数组
var troop=new Array(2,3,5,6,4,7);

数组方法:

var str="I love javascript";
var single=str.split("");           //'I',' ','l','o',.....
var mutipy=str.split(" ");        //'I','love','javascript'


var troop=new Array(2,5,6,8,9,4,1,2);
var index=troop.indexOf(2);    //index=0

var names=['jack','mike','molly'];
var str=names.join();               //str='jack,mike,molly'

var nums=[];
nums.push(3,4);
nums.shift(1,2);                      //nums=[1,2,3,4];
nums.pop();                           //nums=[1,2,3];
nums.shift();                          //nums=[2,3];
nums.splice(0,1,5,6)                //nums=[5,6,3];

对数组元素进行操作(不产生新数组) var nums=[2,4,6,8]; function isEven(num){return num%2==0;}
function square(num){return num*num;}
nums.forEach(square); //对数组所有元素平方
var swit=nums.every(isEven); //判断数组元素是否均为偶数,若是,返回true;

产生新数组:
filter,map

二元数组:
for(var i=0;i<5;i++)
troop[i]=[];

栈和列表其实就是对数组和数组方法的封装,所以我省略不写。 

链表:

    var linkLIst=function(){
        var Node=function(element){
            this.element=element;
            this.next=null;
        };
        this.length=0;        
        this.head=new Node("head");                 //定义链表头,长度,同时,定义了四个方法。
        this.append=append;
        this.insert=insert;        
        this.remove=remove;
        this.display=display;
        
        function append(element){
            var newNode=new Node(element);          //链表在末尾添加新节点,注意的是,node.next仍是node类型,故在添加新节点时要调用节点构造函数
            var thisNode=this.head;
this.length++;
if(thisNode.element==null) //在写循环语句或者判断语句的时候要注意,一个空节点是没有element元素的, { //因此要先确保thisNode为非空节点,该if判断语句才能正常运行,不然会报错。 thisNode.element=element; }else{ while(thisNode.next) { thisNode=thisNode.next; } thisNode.next=newNode; } }; function insert(elementbe,element){ var nodebe=this.head; this.length++; var insertNode=new Node(element); while(!(nodebe.element===elementbe)){ nodebe=nodebe.next; }; var nodeafter=nodebe.next; nodebe.next=insertNode; insertNode.next=nodeafter; }; function remove(element){ var nodeDelete=this.head; while(!(nodeDelete.next.element===element)) { nodeDelete=nodeDelete.next; }; var nodeAfter=nodeDelete.next.next; //next可叠加多次 nodeDelete.next=nodeAfter; }; function display(){ var thisNode=this.head; var str=""; while(thisNode){ str+=thisNode.element+" "; thisNode=thisNode.next; } return str; } }; var newlist=new linkLIst(); //如果调用构造函数为什么用new不太理解,可以参考上一篇博文我对this的简析 newlist.append("1");newlist.append("2");newlist.append("3");newlist.append("4");newlist.insert("3","5") var str=newlist.display(); alert(str);

 字典:字典类型实际上和数组差不多,但要关注的是,字典类型的键通常为字符串,不是像数组中从0递增,因此,在展示全部元素时与数组有所区别

var myDictionary=function(){
this
.dataStore=new Array(); this.add=add; this.find=find; this.showAll=showAll; this.remove=remove; function add(key,value){ this.dataStore[key]=value; }; function find(key){ return
this.dataStore[key]; }; function remove(key){ delete this.dataStore[key]; //这个方法只删除key对应的值 }; function showAll(){ var arr=new Array(),i=0; for (var key in this.dataStore) //key实际上是数组里面的元素? { //某本书上有错误的范例(var key in Object.keys(this.dataStore)),该语句中key的值为0,1,2,3....故只适用于一般数组 arr[i++]=key+" "+this.dataStore[key]; } return arr; }; }; var dict=new myDictionary(); dict.add("one","Mike");dict.add("two","John");dict.add("three","Molly"); var show=dict.showAll(); alert(show);

 hash table(散列表):

    var hashTable=function(){
        this.table=new Array(137);                  //先定义表的大小,因为后面的哈希值要通过表大小来确定
        this.simpleHash=simpleHash;                 //求得哈希值           
        this.showDistro=showDistro;                 //展示所有元素,返回一个字符串
        this.put=put;                               //将新元素加入表中
        
        function simpleHash(data){
            var hash=0;
            for(var i=0;i<data.length;i++)
            {
                hash+=data.charCodeAt(i);           //函数charCodeAt()返回字符串某个元素的ASC码值,这里用循环得到字符串ASC码值之和
            }
            return hash % 137;                      //将码值之和除以表大小,所得余数为键,这样可以确保键的数值大小始终小于表的大小
        };
        function showDistro(){
            var i=0;
            str="";
            while(i++<this.table.length)
            {
                if(this.table[i]!=null)              //由上面哈希表创建过程可知哈希表有一些键值是未定义的,因此要过滤掉这些元素
                {
                    str+=i+" "+this.table[i]+" .";
                }
            }
            return str;
        };
        function put(data){
            var i=simpleHash(data);
            this.table[i]=data;
        };
        
    };
    var tab=new hashTable();
    tab.put("abc");tab.put("sdf");
    var output=tab.showDistro();
    alert(output);

 分析上面代码,可以发现一个问题,两个字符串asc码值之和相同,那么后者会把前者覆盖,这个问题有三种解决方法,一为将hash值转换过程改善,通常采用的是与等比数列相乘,二为在哈希表中创建链表,这样,即使哈希值相同,所有的元素都能展现,三为将后来者往下移,填补到空缺的位置。

            function betterHash(data){                                //第一种方法。
                var hashNum=0;                                        //用betterHash代替原有方法,可以使数据更分散。
                for(var i=0;i<data.length;i++){
                    hashNum=data.charCodeAt(i)+hashNum*37             //注意的是这里要乘一个质数,当然,不同的质数效果不同,实际情况要多次实验?
                }
                return hashNum;
            }

二叉树:

    var BST=function(){
        this.root=null;
        this.add=add;
        this.remove=remove;
        this.showAll=showAll;        
        var Node=function(data,left,right){
            this.data=data;
            this.left=left;
            this.right=right;
            };

        function add(data){
            var newNode=new Node(data,null,null)
            if(this.root===null){
                this.root=newNode;                
            }else{
                var lastNode=this.root;                
                while(lastNode){
                    if(data>lastNode.data){                //按数据大小排序
                        if(lastNode.right!=null){
                            lastNode=lastNode.right;  
                        }else{
                            lastNode.right=newNode;return;
                        }                        
                    }else{
                        if(lastNode.left!=null){
                            lastNode=lastNode.left;
                        }else{
                            lastNode.left=newNode;return;
                        }                        
                    }
                };
            }
        };
        function remove(data){
            var deleteNode=this.root;
            while(deleteNode){
                if(deleteNode.data>data){
                    deleteNode=deleteNode.left;
                }else if(deleteNode.data<data){
                    deleteNode=deleteNode.right;
                }else if(deleteNode.data===data){
                    deleteNode=null;
                }
            };
        };
        function putStr(data){
            var newInsert=$("<p></p>");
            newInsert.html(data);
            $("body").append(newInsert);
        };

        function showAll(Node) {                       
            if (!(Node.data === null)) {                                
                putStr(Node.data); //此句放前为先序,放中间为中序,放后面为后序
                if(Node.left!=null){
                    showAll(Node.left);
                }
                if(Node.right!=null){
                    showAll(Node.right);  
                }
            }
            return;
        };
    };
    var tt=new BST();
    tt.add(2);tt.add(3);tt.add(7);tt.add(1);tt.add(9);tt.add(4);tt.add(5);alert(tt.root.data);
    tt.showAll(tt.root);

二叉树的难点是遍历,由于二叉树只有向下通道,而没有向上通道,所以一般采用迭代遍历。

图:图的难点在于深度搜索算法和广度搜索算法的实现

            var Graph=function (v){
                this.vertices=v;                           //顶点个数
                this.edges=0;                              //边的条数
                this.adj=[];                               
                //下面是深度,广度搜索算法实现的条件,将所有元素先标记为未访问。
                this.mark=[];
                for(var i=0;i<this.vertices;i++){
                    this.mark[i]=false;
                }    
                //                
                for(var i=0;i<this.vertices;i++){
                    this.adj[i]=[];                       //将每个顶点相邻元素放入一个数列,则一共有V个数列,并且,数列长度必小于V
                }
                this.add=add;
                this.showGraph=showGraph;
                this.deepSearch=deepSearch;
                this.wideSearch=wideSearch;
                function add(v,w){
                    this.adj[v].push(w);                          //这个图类是无指向性的图。
                    this.adj[w].push(v);
                    this.edges++;
                };
                function putStr(data){
                    var str=$("#output").html();
                    str+=data;                    
                    $("#output").html(str);
                };
                function showGraph(){
                    for(var i=0;i<this.vertices;i++){
                        putStr(i+"  ->");
                        for(var j=0;j<this.vertices;j++){
                            if(this.adj[i][j]!=null){
                                putStr(this.adj[i][j]+" ");
                            }                            
                        }
                        putStr('|');
                    }
                };    

                function deepSearch(v){
                    this.mark[v]=true;
                    putStr("mark:"+v+"visited!");               //深度搜索算法中,从顶端元素一直探索到最远路径,然后,再探索另一条路径。
                    alert(this.adj[v]);                         //实现方法也较为简单,依次递归调用函数取得当前元素相邻、未访问过的元素,这样,可以得到最深的图。
                    for (var i=0;i<this.adj[v].length;i++){            
                        if(this.mark[this.adj[v][i]]!=true){                            
                            this.deepSearch(this.adj[v][i]);
                        }                        
                    }
                };
                function wideSearch(v){    
                    var queue=[];
                    queue.push(v);
                    this.mark[v]=true;
                                        
                    for(var i=0;i<this.adj[v].length;i++){        //广度搜索算法中,先遍历与首元素相邻的元素,再遍历与这些元素相邻的元素,用队列可以完美解决这个问题,先将一级相邻元素
                        if(this.mark[this.adj[v][i]]!=true){      //放入队列中,然后挨个取出队列元素,将队列元素的相邻元素也放入队列中。
                            queue.push(this.adj[v][i]);
                            alert("push"+" "+this.adj[v][i]);
                            this.mark[this.adj[v][i]]=true;
                        }                    
                    }                    
                    putStr(queue.shift());
                    if(queue[0]!=null){
                        var out=queue.shift();
                        this.wideSearch(out);
                    }
                };
            };
原文地址:https://www.cnblogs.com/puffmoff/p/7246809.html