二叉堆排序

http://blog.csdn.net/ruanjiayou/article/details/51173973 中的是堆排序,将数组看成完全二叉树来进行排序的。

这里我再补充二叉树的结构和二叉堆排序,插入删除方法、递归的三种遍历、非递归的三种遍历、巧妙的morris算法(第三种没有)、深度/广度优先遍历

我自己测试过,都得到了正确的结果。

1.测试的html页面

<!DOCTYPE html>
<html>
<head>
    <title>二叉树</title>
    <meta charset="UTF-8" />
    <meta name="Author" content="阮家友">
    <meta name="Keywords" content="HTML,model,test">
    <meta name="Description" content="special effect">
    <meta name="time" content="2016-4-23 00:05:36">
    <link rel="stylesheet" href="css/reset.css" type="text/css"/>
    <style type="text/css">
        #center {width:800px;margin:0 auto;padding:50px;}
    </style>
</head>
<body>
    <div id="center">
        <p>二叉堆排序</p>
        <p>用于测试</p>
    </div>
<script type="text/javascript" src="suanfa.js"></script>
<script type="text/javascript">

var btree = new BinaryTree();

//完全二叉树
//var arr1 = [7,9,8,6,5,4,3,2,1,0];
//btree.Init(arr1);
//btree.add(11);
//btree.sort();

//二叉排序树
btree.InsertBST(new BinaryTreeNode(7));
btree.InsertBST(new BinaryTreeNode(9));
btree.InsertBST(new BinaryTreeNode(8));
btree.InsertBST(new BinaryTreeNode(6));
btree.InsertBST(new BinaryTreeNode(5));
btree.InsertBST(new BinaryTreeNode(4));
btree.InsertBST(new BinaryTreeNode(3));
btree.InsertBST(new BinaryTreeNode(2));
btree.InsertBST(new BinaryTreeNode(11));
btree.InsertBST(new BinaryTreeNode(1));
btree.InsertBST(new BinaryTreeNode(0));

btree.DeleteBST(btree.root,9);

console.log(btree);
btree.bfv();//广度优先
//btree.dfv();// 深度优先

//递归先序遍历
//btree.Preorder_traversal_recursion(btree.root);
//递归中序遍历
//btree.Middle_order_traversal(btree.root);
//递归后序遍历
//btree.Post_order_traversal(btree.root);

//非递归先序遍历
//btree.Preorder_traversal_unrecursion(btree.root);
//非递归中序遍历
//btree.Middle_order_untraversal(btree.root);
//非递归后序遍历
//btree.Post_order_untraversal(btree.root);

//非递归 不用栈遍历
//btree.morrisPre(btree.root);
//btree.morrisMid(btree.root);
</script>
</body>
</html>

2.对http://blog.csdn.net/ruanjiayou/article/details/51173973中suanfa.js的补充

//二叉树的节点类
function BinaryTreeNode(data){
    this.left = null;
    this.data = data;
    this.right = null;
}
function BinaryTree(){
    this.root = null;
}
//用的完全二叉树插法
BinaryTree.prototype.Init = function(arr){
    var len = arr.length;
    for(var i = 0;i < len;i++){
        this.add(arr[i]);
    }
}
//完全二叉树插入法  广度优先
BinaryTree.prototype.add = function(v){
    var tempNode = null;
    var tempQueue = new Queue();
    if(this.root!=null){
        tempQueue.push(this.root);
    }
    else{
        this.root = new BinaryTreeNode(v);
    }
    while(tempQueue.isEmpty()==false){
        tempNode = tempQueue.shift();
        if(tempNode.left==null){
            tempNode.left = new BinaryTreeNode(v);
            break;
        }
        else{
            tempQueue.push(tempNode.left);
        }
        if(tempNode.right==null){
            tempNode.right = new BinaryTreeNode(v);
            break;
        }
        else{
            tempQueue.push(tempNode.right);
        }
    }
}
//二叉排序树 所有左子树小于根,所有右子树大于根
BinaryTree.prototype.SearchBST = function(tempNode,op,o){
    if(tempNode==null){
        return op;
    }
    if(tempNode.data==o.data){
        return true;
    }
    else{
        if(tempNode.data < o.data){
            return this.SearchBST(tempNode.right,tempNode,o);
        }
        else{
            return this.SearchBST(tempNode.left,tempNode,o);
        }
    }
}
//二叉排序树插入法 Binary Sort Tree
BinaryTree.prototype.InsertBST = function(o){//new BinaryTreeNode()
    var tempNode = null;
    if(!this.root){
        this.root = o;
        return true;
    }
    else{
        tempNode = this.SearchBST(this.root,this.root,o);
        if(true === tempNode){
            console.log("树中已有相同的数据(关键字)");
            return false;//树中已有相同的数据(关键字)
        }
        else{
            if(tempNode.data > o.data){
                tempNode.left = o;
            }
            else{
                tempNode.right = o;
            }
            return true;
        }
    }
}
//二叉排序树 删除  
BinaryTree.prototype.DeleteBST = function(tempNode,v){
    if(null==tempNode){
        return false;
    }
    if(tempNode.data == v){
        console.log("find node value="+v);
        return this.Delete(tempNode);
    }
    else{
        if(tempNode.data < v){
            this.DeleteBST(tempNode.right,v)
        }
        else{
            this.DeleteBST(tempNode.left,v)
        }
    }
}
//delete有问题
BinaryTree.prototype.Delete = function(tempNode){
    if(tempNode.left==null){
        tempNode = tempNode.right;
        return true;
    }
    if(tempNode.right==null){
        tempNode = tempNode.left;
        return true;
    }
    //被删除的节点N 左子树都小于N.data且大于N的父节点 右子树都大于 N.data
    //所以删除N就是将左子树的最大值(左子树最右侧)辅助给N 
    var q = tempNode;
    var s = tempNode.left;
    while(s.right!=null){
        q = s;
        s = s.right;
    }
    tempNode.data = s.data;
    if(q!=tempNode){
        q.right = s.left;
    }
    else{
        q.left = s.left;
    }
    return true;
}
//广度优先遍历  没问题
BinaryTree.prototype.bfv = function(){
    var tempQueue = new Queue();
    var tempNode = null;
    if(this.root!=null){
        tempQueue.push(this.root);
    }
    while(tempQueue.isEmpty()==false){
        tempNode = tempQueue.shift();
        if(tempNode.left!=null){
            tempQueue.push(tempNode.left);
        }
        if(tempNode.right!=null){
            tempQueue.push(tempNode.right);
        }
        console.log(tempNode.data);
    }
}
//深度优先遍历  确实是深度优先 
BinaryTree.prototype.dfv = function(){
    var stack = new Stack();
    var tempNode = null;
    if(this.root!=null){
        stack.push(this.root);
    }
    while(stack.isEmpty()==false){
        tempNode = stack.pop();
        console.log(tempNode.data);
        if(tempNode.right!=null){
            stack.push(tempNode.right);
        }
        if(tempNode.left!=null){
            stack.push(tempNode.left);
        }
    }
}
//前序遍历 访问根节点,访问遍历左子树(遍历时还是先访问根节点),遍历右子树(遍历时还是先访问根节点)
//递归方法
BinaryTree.prototype.Preorder_traversal_recursion = function(tempNode){
    if(tempNode!=null){
        console.log(tempNode.data);
        this.Preorder_traversal_recursion(tempNode.left);
        this.Preorder_traversal_recursion(tempNode.right);
    }
}
//中序遍历 投影法
BinaryTree.prototype.Middle_order_traversal = function(tempNode){
    if(tempNode!=null){
        this.Middle_order_traversal(tempNode.left);
        console.log(tempNode.data);
        this.Middle_order_traversal(tempNode.right);
    }
}
//后序遍历
BinaryTree.prototype.Post_order_traversal = function(tempNode){
    if(tempNode!=null){
        this.Post_order_traversal(tempNode.left);
        this.Post_order_traversal(tempNode.right);
        console.log(tempNode.data);
    }
}
//非递归方法
//前序遍历
BinaryTree.prototype.Preorder_traversal_unrecursion = function(tempNode){
    var stack = [];
    if(tempNode!=null){
        stack.push(tempNode);
        while(stack.length!=0){
            tempNode = stack.pop();
            console.log(tempNode.data);
            if(tempNode.right!=null){
                stack.push(tempNode.right);
            }
            if(tempNode.left!=null){
                stack.push(tempNode.left);
            }
        }
    }
}
//中序遍历
BinaryTree.prototype.Middle_order_untraversal = function(tempNode){
    var stack = [];
    if(tempNode!=null){
        while(stack.length!=0 || tempNode){
            if(tempNode){
                stack.push(tempNode);
                tempNode = tempNode.left;
            }
            else{
                tempNode = stack.pop();
                console.log(tempNode.data);
                tempNode = tempNode.right;
            }
        }
    }
}
//后序遍历
BinaryTree.prototype.Post_order_untraversal = function(tempNode){
    var stack = [];
    var tmp = null;
    if(tempNode!=null){
        stack.push(tempNode);
        while(stack.length!=0){
            tmp = stack[stack.length-1];
            if(tmp.left && tempNode!==tmp.left && tempNode!==tmp.right){
                stack.push(tmp.left);
            }
            else{
                if(tmp.right && tempNode!==tmp.right){
                    stack.push(tmp.right);
                }
                else{
                    console.log(stack.pop().data);
                    tempNode = tmp;
                }
            }
        }
    }
}
//非递归 不用栈遍历
BinaryTree.prototype.morrisPre = function(head){
    var cur1 = head,cur2 = null;
    if(head!=null){
        while(cur1){
            cur2 = cur1.left;
            if(cur2){
                while(cur2.right && cur2.right!==cur1){
                    cur2 = cur2.right;
                }
                if(!cur2.right){
                    cur2.right = cur1;
                    console.log(cur1.data);
                    cur1 = cur1.left;
                    continue;
                }
                else{
                    cur2.right = null;
                }
            }
            else{
                console.log(cur1.data);
            }
            cur1 = cur1.right;
        }
    }
}
BinaryTree.prototype.morrisMid = function(head){
    var cur1 = head,cur2 = null;
    if(head){
        while(cur1){
            cur2 = cur1.left;
            if(cur2){
                while(cur2.right && cur2.right !==cur1){
                    cur2 = cur2.right;
                }
                if(!cur2.right){
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                }
                else{
                    cur2.right = null;
                }
            }
            console.log(cur1.data);
            cur1 = cur1.right;
        }
    }
}
BinaryTree.prototype.morrisPos = function(head){
    var cur1 = head, cur2 = null;
    if(head){
        while(cur1){
            cur2 = cur1.left;
            if(cur2){
                while(cur2.right && cur2.right !== cur1){
                    cur2 = cur2.right;
                }
                if(!cur2.right){
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                }
                else{
                    cur2.right = null;
                    this.printEdge(cur1.left);
                }
            }
            cur1 = cur1.right;
        }
        this.printEdge(head);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值