二叉堆排序

本文介绍了一种通过HTML与JavaScript实现的二叉树及二叉堆排序方法,包括二叉树的初始化、插入、删除操作,并演示了递归与非递归的遍历方式,以及Morris遍历算法。

http://blog.youkuaiyun.com/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.youkuaiyun.com/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);
    }
}


<think>好的,我需要回答用户关于完全叉树(complete binary tree)的定义的问题。首先,我得回忆一下完全叉树的基本概念,确保自己理解正确。根据已有的知识,完全叉树是一种特殊的叉树结构,它的节点排列需要满足一定的条件。 接下来,我要检查用户提供的引用资料,看看是否有相关的信息可以支持我的回答。用户提到了引用[2]和引用[4],其中引用[2]提到完全叉树的特点是层次遍历没有中断点,可以用数组实现。而引用[4]则强调不要将满叉树与完全叉树混淆,说明两者是不同的概念。 我需要明确完全叉树的定义,可能包括以下几点:完全叉树除了最后一层外,其他层都是满的,并且最后一层的节点都尽可能靠左排列。这与满叉树不同,满叉树所有层都是满的。同时,完全叉树可以用数组高效存储,因为节点之间没有空隙。 然后,我需要组织语言,用中文清晰表达这一定义,并引用相关的资料来支持。例如,引用[2]提到完全叉树的层次遍历没有中断点,适合数组实现,这可以作为一个引用点。引用[4]则用来区分完全叉树和其他类型的树,如满叉树。 另外,用户要求生成相关问题,我需要根据完全叉树的定义和应用,提出几个相关的问题,比如与满叉树的区别、应用场景、数组实现方式等。 最后,确保回答结构清晰,使用正确的LaTeX格式,如变量用$...$,独立公式用$$...$$,并且检查引用标注是否自然添加在段落末尾。避免使用任何Markdown格式,保持回答简洁明了。</think>### 完全叉树(Complete Binary Tree)的定义 完全叉树是一种满足以下性质的叉树: 1. **除最后一层外,其他层节点数达到最大值**,即每层都是满的; 2. **最后一层的节点必须从左到右连续排列**,不能有空缺[^2][^4]。 例如,若一棵完全叉树的深度为$h$,则前$h-1$层的节点构成满叉树,第$h$层的节点依次填充左侧位置。这种特性使得完全叉树可以用数组高效存储,因为其层次遍历结果与数组顺序一致,且无“空洞”[^2]。 #### 与满叉树的区别 - **满叉树**:所有层的节点数均达到最大值,即深度为$k$的满叉树有$2^k - 1$个节点; - **完全叉树**:仅要求最后一层左侧连续填充,其他层满,节点数可能少于满叉树。 #### 应用场景 完全叉树常用于(Heap)的实现(如优先队列),或需要数组存储的高效树结构[^2]。 ```python # 完全叉树的数组表示示例 tree = [1, 2, 3, 4, 5, 6, None] # 最后一层左侧连续,右侧允许None ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值