数据结构----->二叉树
来源:互联网 发布:mysql 断电 无法启动 编辑:程序博客网 时间:2024/05/23 18:31
(1)数据结构----二叉树
具有数组和链表各自的特点:
1>像数组一样快速的查找
2>像链表一样快速添加
3>删除操作复杂
二叉树:每个节点最多有两个字数的有序树,在使用二叉树的时候,数据并不是随便插到节点中的,一个节点的左字节点的关键值必须小于此节点,右子节点的关键值必须大于或者等于此节点,所以称二叉查找树,二叉排序树,二叉搜索树.
完全二叉树:若设二叉树的高度为h,除第h层外,其他各层的节点数都达到最大个数,第h层有叶子节点,并且叶子节点都是从左到右一次排布
满二叉树:除了叶节点以外,每个节点都有左右孩子
深度:二叉树的层数
二叉树的(特点):
(1):树执行查找,删除,插入的时间复杂度都是O(logN)
(2):遍历二叉树的方法包括前,中,后
(3):非平衡树指的是根的左右两边的子节点的数量不一致
(4):在非空二叉树中,第i层的节点总数不超过2^(n-1)
(5):深度为h的二叉树最多有2^(h)-1
(6):对于任意一颗二叉树,如果其叶节点数为N0,而度为二的节点数为N2则N0=N2+1;
/** 树的节点定义*/class Node { private Node lchild;// 左孩子 private Node rchild;// 右孩子 private int value; private boolean isDelete; public Node getlchildNode() { return lchild; } public void setlchildNode(Node lchild) { this.lchild = lchild; } public Node getrchildNode() { return rchild; } public void setrchildNode(Node rchild) { this.rchild = rchild; } public int getValue() { return value; } public void setValue() { this.value = value; } public boolean getdelete() { return isDelete; } public void setdelete(boolean isDelete) { this.isDelete = isDelete; } public Node() { } public Node(Node lchild, Node rchild, int value, boolean isDelete) { super(); this.lchild = lchild; this.rchild = rchild; this.value = value; this.isDelete = isDelete; } public Node(int value) { this(null, null, value, false); } public String toString() { return "Node[lchild=" + lchild + ",rchild=" + rchild + ",value=" + value + ",isDelete=" + isDelete + "]"; }}/** 二叉树的实现代码 ,插入操作*/class BTree { // 根节点 private Node root; public Node getRoot() { return root; } /** 插入操作 */ public void insert(int value) { Node node = new Node(value); if (root == null) { root = node; root.setlchildNode(null); root.setrchildNode(null); } else { Node currentNode = root; Node parentNode; while (true) { parentNode = currentNode; if (node.getValue() > currentNode.getValue()) { currentNode = currentNode.getrchildNode(); if (currentNode == null) { parentNode.setrchildNode(node); return; } } else { // 左边 currentNode = currentNode.getlchildNode(); if (currentNode == null) { parentNode.setlchildNode(node); return; } } } } }}
/* 二叉树的查找 /
public Node find(int key) {
Node currentNode = root;
if (currentNode != null) {
while (currentNode.getValue() != key) {
if (currentNode.getValue() > key) {
currentNode = currentNode.getlchildNode();
} else { currentNode = currentNode.getrchildNode(); } if (currentNode == null) { return null; } } if (currentNode.getdelete()) { return null; } else { return currentNode; } } else { return null; } }}
/* 构建完全二叉树 /
public CreateTree() {
pnum = aa.length / 2;
root = null;
nodelist = new LinkedList();
for (int index = 0; index < aa.length; index++) {
nodelist.add(new Node(aa[index]));
} for (int i = 0; i < pnum; i++) { pnode = nodelist.get(i);// 拿到父亲节点 // 设置左孩子 pnode.setlchild(nodelist.get(2 * i + 1)); if ((2 * i + 2) < nodelist.size()) { // 右孩子 pnode.setrchild(nodelist.get(2 * i + 2)); } // 因为最后一个父节点可能没有右孩子,所以单独拿出来处理 int lastpnode = aa.length / 2 - 1; nodelist.get(lastpnode).lchild = nodelist.get(lastpnode * 2 + 1); if (aa.length % 2 == 1) { nodelist.get(lastpnode).rchild = nodelist .get(lastpnode * 2 + 2); } }}/** 前序遍历 */public static void pro(Node node) { if (node == null) { return; } System.out.print(node.data + ""); pro(node.lchild); pro(node.rchild);}/** 中序遍历 */public static void Ino(Node node) { if (node == null) { return; } Ino(node.lchild); System.out.print(node.data + ""); Ino(node.rchild);}/** 后序遍历 */public static void por(Node node) { if (node == null) { return; } por(node.lchild); por(node.rchild); System.out.print(node.data + "");}/** 非递归----》前序遍历 */ public void preOrder(notTree t) { // 采用顺序 Stack<notTree> s = new Stack<notTree>(); while (t != null || !s.empty()) { while (t != null) { System.out.print(t.data); s.push(t);//入栈 t=t.lchild; } if(!s.empty()){ t=s.pop();//出栈 t=t.rchild; } } }
/*非递归中序遍历/
public void InOrder(notTree t){
Stack ss=new Stack();
while(t!=null||!ss.empty()){
while(t!=null){
ss.push(t);
t=t.lchild;
}
if(!ss.empty()){
ss.pop();
System.out.print(t.data);
t=t.rchild;
} } } /**非递归后序 */
这里需要说明一下,后序遍历相对于前面的来说相对比较复杂。
二叉树的后序遍历顺序为,root–>lchild,rooot—>rchild, root.
所以我们要保存根节点的状态,用栈来模拟递归的过程
方法:对于节点s有以下情况
1>s如果是叶子节点,直接输出
2>s如果有孩子,且孩子没有被访问过,则按照右孩子,左孩子的顺序依次入栈
3>s如果有孩子,且孩子都已经访问过,则访问s节点
(1)(怎样来表示s是否被访问过,一般都会想到对每个节点的状态进行保存,但是空间复杂度太大)
(2)可以保存最后一个访问的节点last如果满足(p-rchild>NULL&&p->lchild||last=p->rchild)那么显然我们p的孩子都访问过了,接下来访问p)
/*二叉树非递归后序遍历 /
public void PostOrder(notTree t) { Stack<notTree> sss = new Stack<notTree>(); Stack<Integer> s2 = new Stack<Integer>(); Integer i = new Integer(1); while (t != null || !sss.empty()) { while (t != null) { sss.push(t); s2.push(new Integer(0)); t = t.lchild; } while (!sss.empty() && s2.peek().equals(i)) { s2.pop(); System.out.print(sss.pop().data); } if (!sss.empty()) { s2.pop(); s2.push(new Integer(1)); t = sss.peek(); t = t.rchild; } } }
- 数据结构-树-二叉树
- 数据结构::树,二叉树
- 数据结构-二叉树
- 二叉树的数据结构
- 数据结构-二叉树算法
- java数据结构:二叉树
- 数据结构---二叉树
- 数据结构(C++)--二叉树
- JAVA 数据结构 二叉树
- 数据结构-二叉树 问题
- 转贴:数据结构:二叉树
- 二叉树(数据结构 c++)
- 数据结构-二叉树操作
- java数据结构----二叉树
- 数据结构二叉树
- 数据结构中的二叉树
- 数据结构--二叉树
- 数据结构二叉搜索树
- MDK的编译过程及文件类型全解
- 栈的基本操作
- 字符串基础问题
- done and doing
- Git .gitignore文件比较完善的写法
- 数据结构----->二叉树
- BF算法
- hdu3487:Play with Chain (splay)
- spoj10606——BALNUM
- 51nod:1174 区间中最大的数(RMQ)
- java 计算两字符串的最大子字符串
- FullCalendar – jQuery Event Calendar in ASP.NET
- cc2540 usb hid升级
- 电子元件的学习