大顶堆 堆排序 例子
import java.lang.reflect.Array;
import java.util.Arrays;
public class heapSortTest {
public static void main(String[] args) {
int []x = {4,6,8,5,9};
heapSort heapSort = new heapSort();
heapSort.setHeapSort(x);
System.out.println(Arrays.toString(x));
heapSort.dpx(x);
}
}
//堆排序
class heapSort{
int temp;//用来堆排序时 当跳板 来交换值
//利用堆排序给数组排序
public void dpx(int []x){
//调用堆排序方法 先将数组转换为大顶堆
setHeapSort(x);
//然后按照顺序从最后一个元素 到根节点的后面一个元素(也就是不包括根节点) 进行循环
for (int i=x.length-1;i>0;i--){
//交换根节点的值和 i当前所表示的索引的值
temp = x[i];
x[i] = x[0];
x[0] = temp;
//调整交换过后的数组再次为大顶堆(因为现在调整的是 去除根节点原本那个最大值的数组(比较特殊) 为大顶堆 所以直接传入根节点 从上向下调整数组)
setHeapSort(0,x,i);
}
//输出堆排序后的数组
System.out.println(Arrays.toString(x));
}
//首先需要将数组转换为大顶堆的排序方式
public void setHeapSort(int []x){
//首先查看数组有没有被赋予值 和数组的长度是否为0
if (x.length==0||x==null){
return;
}
//x.length/2-1 代表的是当前顺序树的最后一个非叶子节点的节点 这个循环就是从这个节点到根节点的循环
//因为转换堆排序的时候是从下至上 从左至右转换的
for (int i =x.length/2-1 ; i >=0 ; i--) {
//按照从下至上 从左至右转换的顺序轮流将所有非叶子节点的节点传入 即按顺序逐步将整个数组转换为大顶堆的排序
setHeapSort(i,x,x.length);
}
}
//一个数组实际是一个顺序树 将一个顺序树转换为大顶堆需要传入 当前根节点的索引 数组 和当前根节点代表的数的大小
public void setHeapSort(int i,int []x,int arrlength){
int temp = x[i];//先将当前根节点的值存起来(后续需要用到)
//从当前节点的左子节点开始循环 每过一轮 g就变成刚才节点的左子节点的左子节点 知道那个节点不存在(索引超出数组长度)就结束循环
for (int q=i*2+1;q<arrlength;q=q*2+1){
//然后比较传入的节点的左右子节点之间的大小 q默认代表左子节点 如果右子节点的值大于他 那么q++ 使q代表右子节点
if (q+1<arrlength&&x[q] < x[q+1]){
q++;
}
//用索引为q的值跟传入的节点的值进行比较 如果x[q]>x[i] 那么把根节点的值变成q的值 并使i=q i代表q的索引 来保证根节点的值大于子节点
if (x[q]>temp){
x[i] = x[q];
i = q;
}else{//如果当前节点的子节点的值都小于自己 那么跳出循环
break;
}
}
//将temp 也就是根节点的值 付给x[i](如果当前节点的子节点的值大于自己 那么在里面进行判断过后 i现在就代表你交换的那个子节点的索引 如果不大于 那么他还是自己)
x[i] = temp;
}
}
二叉排序树例子
package test1;
public class binarySortTreeTest {
public static void main(String[] args) {
int []x = {5,3,9,7,6,4,2};
String []z = {"阿狸","亚索","鱼人","猴子","琴女","螳螂","卡牌"};
binarySortTree tree = new binarySortTree();
for (int i = 0; i < x.length; i++) {
tree.add(x[i],z[i]);
}
System.out.println("二叉排序树");
tree.fixOrder();
// node test1 = tree.searchf(9);
// System.out.println(test1);
System.out.println("删除后的二叉排序树");
tree.delete(5);
tree.fixOrder();
}
}
//创建二叉排序树树
class binarySortTree{
//根节点
node root;
public void add(int id, String name){
if (root == null){
root = new node(id,name);
}else{
node test = new node(id,name);
root.add(test);
}
}
//二叉排序树中序遍历
public void fixOrder(){
if (root == null){
System.out.println("树空!!!!");
}else{
root.fixOrder();
}
}
//搜索目标节点
public node search(int id){
if (root == null){
return null;
}
return root.search(id);
}
//搜索目标节点的父节点
public node searchf(int id){
if (root == null){
return null;
}
node mb = root.search(id);
return root.searchf(mb);
}
//找以目标节点的右子节点为根节点的情况下 值最小的节点 获取并返回他的值 并删除这个最小节点
public Object[] searchlittle(node node){
while (node.left!=null){
node = node.left;
}
Object[] mb = {node.id,node.name};
node delmb = searchf(node.id);
if (delmb.left==node){
delmb.left = null;
}else{
delmb.right = null;
}
return mb;
}
//通过id删除目标节点
public void delete(int id){
node target = this.search(id);
node ftarget = this.searchf(target.id);
if (target != null){
//目标节点没有子节点的情况
if (target.left == null && target.right == null) {
if (ftarget.left == target) {
ftarget.left = null;
}
if (ftarget.right == target) {
ftarget.right = null;
}
//目标节点有两个子节点的情况
}else if (target.left!=null&&target.right!=null){
Object[] x = searchlittle(target.right);
target.id = (int) x[0];
target.name = (String) x[1];
//那么剩下的就是只有一个子节点的情况
}else{
if (ftarget!=null) {
if (ftarget.left == target) {
if (target.left != null) {
ftarget.left = target.left;
}
if (target.right != null) {
ftarget.left = target.right;
}
} else {
if (target.left != null) {
ftarget.right = target.left;
}
if (target.right != null) {
ftarget.right = target.right;
}
}
}else{
if (target.left!=null){
root = target.left;
}else{
root = target.right;
}
}
}
}else{
System.out.println("未找到目标,删除失败!");
}
}
}
//创建节点
class node{
//id
int id;
String name;
node left;
node right;
public node(int id,String name){
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "node{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
//给二叉排序树添加节点
public void add(node node){
//如果传入的节点的id 小于 当前节点的值
if (node.id < this.id){
//并且当前根节点的左子节点为空 那么当前节点的左子节点就为 穿的的节点
if (this.left == null){
this.left = node;
}else{
//否则就以当前节点的左子节点为根节点继续添加
this.left.add(node);
}
}else{
if (this.right == null){
this.right = node;
}else{
this.right.add(node);
}
}
}
//中序遍历二叉排序树
public void fixOrder(){
//如果当前节点的左子节点不为空 那么就以当前节点的左子节点为根节点继续找
if (this.left!=null){
this.left.fixOrder();
}
System.out.println(this);
//同上
if (this.right!=null){
this.right.fixOrder();
}
}
//二叉排序树删除节点
//搜索目标节点
public node search(int id){
if (this.id == id){
return this;
}else if (id <this.id){
return this.left.search(id);
}else{
return this.right.search(id);
}
}
//搜索目标节点的父节点
public node searchf(node mb){
if (this.left!=null&&this.left==mb||this.right!=null&&this.right==mb ){
return this;
}
if (mb.id < this.id){
return this.left.searchf(mb);
}
if (mb.id > this.id){
return this.right.searchf(mb);
}
return null;
}
}