二叉树是树结构的一种,一种一对多的逻辑关系,
基本概念:父节点有且最多只有两个子节点
树的名词解释:
根节点:二叉树的顶层节点有且只有一个,如图中的1节点
父节点:相比较的概念的,如:2是5和4的父节点,1是2的父节点
子节点:和父节点一样也相对的 如:对于8和9而言它是4的子节点,而对于4它是2的子节点……
层:它来判断树的高度,如图中有4层
权:指每个节点的存储的值(数据),图中每个节点存储了数字这就是权
路径:指从当前节点到其他节点的路线,如:从2到5的路线就是路线,每个节点都有一个左右指向
叶子节点:没有子节点的节点,如:8,9,10,11,6,7都是叶子节点
子树:类比于一颗大树的树枝,如:2,4,5就叫一颗子树
树的高度:最大层数
------满二叉树和完全二叉树-------
满二叉树:所有的叶子节点都在最后一层,节点的总数=2^n-1(n为层数)
图中就是一个满二叉树,所有节点都在最后一层,它的节点总数=2^3-1为7个节点
完全二叉树:所有的叶子节点都在最后一层或者倒数第二层,最后一层向左连续,倒数第二层向右连续
假如5,6,7其中一个没有就不存在连续也就不完全二叉树
--------二叉树的实现-----------
在数据结构的分类中物理存储分两类:顺序存储和链式存储
在数据结构中每一个逻辑结构都依赖于物理存储结构,通过物理结构来实现逻辑结构
二叉数有两种实现方式,一种是链式存储二叉树,一个顺序存储二叉树(堆的实现依赖于顺序二叉树)
------------链式二叉树-------------
构建图中的二叉树:
public class chaintree { public static void main(String[] args) { //建立节点:定义6个节点 predata a=new predata(1); predata b=new predata(2); predata c=new predata(3); predata d=new predata(4); predata e=new predata(5); predata f=new predata(6); //给他们建立关系 //a点的左节点是b,a的右节点是c a.setLife(b); a.setRight(c); //b的左节点是d,右节点是e b.setLife(d); b.setRight(e); //c的右节点是f,没有左节点 c.setRight(f); //将节点关系放进树里面 tree wql=new tree(a); wql.front();//1,2,4,5,3,6 } } //定义树把节点类的节点联系放进树 class tree{ private predata treewql; public tree(predata treewql){ this.treewql=treewql; } //从树类中调用遍历方法 //前序遍历 public void front(){ if(treewql==null){ System.out.println("树为空"); }else{ treewql.front(); } } //中序遍历 public void centre(){ if(treewql==null){ System.out.println("树为空"); }else{ treewql.centre(); } } //后序遍历 public void later(){ if(treewql==null){ System.out.println("树为空"); }else{ treewql.later(); } } } //节点类 class predata{ private predata life;//定义左子节点 private predata right;//定义右子节点 private int val;//给我树一个权值 //初始化值 public predata(int val){ this.val=val; } //给当前节点设置它的左节点 public void setLife(predata life) { this.life = life; } //给当前节点设置它左节点 public void setRight(predata right) { this.right = right; } //toString方法 @Override public String toString() { return "predata{" + "val=" + val + '}'; } //前序遍历:先输出父节点,再输出左子节点,最后是右子节点 public void front(){ System.out.println(this);//前序遍历首先输当前节点也就是父节点 if(this.life!=null){//输出左子节点,先判断左子节点是否为空,再递归输出左子节点 this.life.front(); } if(this.right!=null){//输出右子节点,先判断右子节点是否为空,再递归输出右子节点 this.right.front(); } } //中序遍历:先输出左子节点,再输出父节,最后是右子节点 public void centre(){ //中序遍历首先输当前节点也就是父节点 if(this.life!=null){//输出左子节点,先判断左子节点是否为空,再递归输出左子节点 this.life.centre(); } //中间输出父节点 System.out.println(this); if(this.right!=null){//输出右子节点,先判断右子节点是否为空,再递归输出右子节点 this.right.centre(); } } //后序遍历:先输出左子节点,再输出右子节点,最后是父节点 public void later(){ //中序遍历首先输当前节点也就是父节点 if(this.life!=null){//输出左子节点,先判断左子节点是否为空,再递归输出左子节点 this.life.later(); } //中间输出右子节点 if(this.right!=null){//输出右子节点,先判断右子节点是否为空,再递归输出右子节点 this.right.later(); } //最后输出父节点 System.out.println(this); } }
前序遍历,中序遍历,后序遍历的区别在于父节点输出的位置,前序就是父节最先输出,以此类推
前序:父节点 -> 左子节点 -> 右子节点
中序:左子节点 ->父节点 -> 右子节点
后序:左子节点 ->右子节点 -> 父节点
----------顺序存储二叉树---------
顺序存储二叉树与链式存储二叉树不同,它的节点是数组的一个个区间,数组中存储的值就是树的权
树的左节点=2*当前节点在数组中的索引+1
树的右节点=2*当前节点在数组中的索引+2
通过索引来计算左右树
如图中:
a的左节点=2*0+1(索引)
c的右节点=2*2+2(索引)
public class ordertree { public static void main(String[] args) { int[] WQL=new int[]{1,2,3,4,5,6}; datawql a=new datawql(WQL); a.alter1(0); //1,2,4,5,3,6 } } class datawql{ int[] datas; public datawql(int[] datas){ this.datas=datas; } //前序遍历 public void front1(int index){//给出要遍历的起始节点的索引 if(datas[index]!=0 && index<datas.length) { System.out.println(datas[index]); } if((index*2+1)<datas.length){ front1(index*2+1); } if((index*2+2)<datas.length){ front1(index*2+2); } } //中序遍历 public void concre1(int index){//给出要遍历的起始节点的索引 if((index*2+1)<datas.length){ concre1(index*2+1); } if(datas[index]!=0 && index<datas.length) { System.out.println(datas[index]); } if((index*2+2)<datas.length){ concre1(index*2+2); } } //中序遍历 public void alter1(int index){//给出要遍历的起始节点的索引 if((index*2+1)<datas.length){//index大于数组长度就声明不存在 alter1(index*2+1); } if(datas[index]!=0 && index<datas.length) { System.out.println(datas[index]); } if((index*2+2)<datas.length){ alter1(index*2+2); } } }
-----------堆排序-----------
堆排序是利用堆这个数据结构而设计的一种排序算法(是一种不稳定排序)
堆是一个完全二叉树它有两个特性:
大顶堆:父节点比子节点大(不比较叶子节点的大小)
小定堆:父节点比子节点小(不比较叶子节点的大小)
public class heapsort { public static void main(String[] args) { int[] a=new int[]{2,3,1,6,4}; heap1 s=new heap1(a); } } //将堆进行排序 class hea1sort{ heap1 c; public hea1sort(heap1 c){ this.c=c; } public void sort(){ for(int a=c.a.length/2-1;a>=0;a--){ c.adjustheap(a); } } } //定义一个堆 class heap1{ int[] a; public heap1(int[] a){ this.a=a; } //将数组的二叉树转化成一个堆 public void adjustheap(int i){//非叶子节点的索引 int[] n=a; int temp=n[i];//保存当前节点的值 for(int i1=i*2+1; i1>=0; i1=i*2+1){ //接收当前节点得到左节点(i*2+1),判断左节点是否比右节点大,如果比右节点小就把左节点的索引改成右索引 if(i1+1<n.length && n[i1+1] >n[i1]){ i1++; } //判断当前非叶子节点的根节点是是否比子节点大,如果小就把子节点的值赋给当前节点也就是a[i] if(i1+1<n.length && n[i] < n[i1]){ n[i]=n[i1]; i=i1;//把i(当前的父节点索引)换成子节点索引 }else { break;//这个方法只判断一个非叶子节点 } n[i]=temp;//如果前后的if条件符号就把之前父节点的值再给子节点 } } }
Comments | NOTHING
Warning: Undefined variable $return_smiles in /www/wwwroot/wql_luoqin_ltd/wp-content/themes/Sakura/functions.php on line 1109