Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 716|回复: 0

[算法学习]java实现的小堆的插入和删除操作

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-12-4 00:08:04 | 显示全部楼层 |阅读模式
    1. import java.util.*;

    2. /**
    3. *实现的小堆的插入和删除操作
    4. * @author Arthur
    5. */
    6. public class Heap {

    7.     /**
    8.      * 递归实现
    9.      * 删除一个堆中一个数据的时候,根据堆的性质,应该把相应的位置下移,才能保持住堆性质不变
    10.      * @param heap 保持堆元素的数组
    11.      * @param index 被删除的那个节点的位置
    12.      */
    13.     public static void heapDown(List< Integer> heap, int index) {
    14.         //因为第一个位置存储的是空值,不在考虑之内
    15.         int n = heap.size() - 2;

    16.         //记录最小的那个儿子节点的位置
    17.         int child = -1;

    18.         //2*index>n说明该节点没有左右儿子节点了,那么就返回
    19.         if (2 * index > n) {
    20.             return;
    21.         } //如果左右儿子都存在
    22.         else if (2 * index < n) {

    23.             //定义左儿子节点
    24.             child = 2 * index;
    25.             //如果左儿子大于右儿子的数值,取右儿子的下标
    26.             if ((Integer) heap.get(child) > (Integer) heap.get(child + 1)) {
    27.                 child++;
    28.             }

    29.         }//如果只有一个儿子(左儿子节点)
    30.         else if (2 * index == n) {
    31.             child = 2 * index;
    32.         }

    33.         if ((Integer) heap.get(child) < (Integer) heap.get(index)) {
    34.             //交换堆中的child,和index位置的值
    35.             swap(heap, child, index);

    36.             //完成交换后递归调用,继续下降
    37.             heapDown(heap, child);
    38.         }
    39.     }

    40.     //非递归实现
    41.     public static void heapDown2(List< Integer> heap, int index) {
    42.         int child = 0;//存储左儿子的位置

    43.         int temp = (Integer) heap.get(index);
    44.         int n = heap.size() - 2;
    45.         //如果有儿子的话
    46.         for (; 2 * index <= n; index = child) {
    47.             //获取左儿子的位置
    48.             child = 2 * index;
    49.             //如果只有左儿子
    50.             if (child == n) {
    51.                 child = 2 * index;
    52.             } //如果右儿子比左儿子的数值小
    53.             else if ((Integer) heap.get(child) > (Integer) heap.get(child + 1)) {
    54.                 child++;
    55.             }

    56.             //如果数值最小的儿子比temp的值小
    57.             if ((Integer) heap.get(child) < temp) {
    58.                 //交换堆中的child,和index位置的值
    59.                 swap(heap, child, index);
    60.             } else {
    61.                 break;
    62.             }
    63.         }
    64.     }

    65.     /**
    66.      * 删除堆中最小的值,也就是删除位置是1的值,也就是根节点的值
    67.      * 操作原理是:当删除根节点的数值时,原来的位置就会出现一个孔
    68.      * 填充这个孔的方法就是,把最后的叶子的值赋给该孔,最后把该叶子删除
    69.      * @param heap
    70.      */
    71.     public static void deleteMin(List< Integer> heap) {
    72.         //把最后的一个叶子的数值赋值给1个位置
    73.         heap.set(1, heap.get(heap.size() - 1));
    74.         //下滤操作
    75.         heapDown2(heap, 1);
    76.        // heapDown(heap, 1);
    77.         //把最后一个位置的数字删除
    78.         heap.remove(heap.size() - 1);
    79.     }

    80.     public static void main(String args[]) {
    81.         List< Integer> array = new ArrayList< Integer>(Arrays.asList(null, 1, 2, 5, 10, 3, 7,
    82.                  11, 15, 17, 20, 9, 15, 8, 16));
    83.         //deleteMin(array);结果是2 3 5 10 9 7 11 15 17 20 16 15 8  
    84.         insert(array, 0);//结果是0 2 1 10 3 7 5 15 17 20 9 15 8 16 11
    85.         print(array);
    86.         System.out.println("-------------------------");
    87.         List< Integer> array1=new ArrayList< Integer>();
    88.         insert(array1,0);//无任何意义,占位.
    89.         insert(array1, 1);insert(array1, 2);insert(array1, 5);insert(array1, 10);insert(array1, 3);insert(array1, 7);
    90.         insert(array1, 11);insert(array1, 15);  insert(array1, 17);insert(array1, 20);insert(array1, 9);
    91.         insert(array1, 15);insert(array1, 8);insert(array1, 16);
    92.         print(array1);
    93.     }

    94.     //打印链表
    95.     public static void print(List< Integer> list) {
    96.         for (int i = 1; i < list.size(); i++) {
    97.             System.out.print(list.get(i) + " ");
    98.         }
    99.         System.out.println();
    100.     }

    101.     //把堆中中的a,b位置的值互换
    102.     public static void swap(List< Integer> heap, int a, int b) {
    103.         //临时存储child位置的值
    104.         int temp = (Integer) heap.get(a);

    105.         //把index的值赋给child的位置
    106.         heap.set(a, heap.get(b));

    107.         //把原来的child位置的数值赋值给index位置
    108.         heap.set(b, temp);
    109.     }

    110.     //向堆中插入元素
    111.     public static void insert(List< Integer> heap, int value) {
    112.         heap.add(value);
    113.         //开始上升操作
    114.         heapUp2(heap, heap.size() - 1);
    115.        // heapUp(heap, heap.size() - 1);

    116.     }

    117.     //上升,让插入的数和父节点的数值比较,当大于父节点的时候就和节点的值相交换
    118.     public static void heapUp(List< Integer> heap, int index) {

    119.         //注意由于数值是从小标为一开始,当index = 1的时候,已经是根节点了
    120.         if (index > 1) {
    121.             //保存父亲的节点
    122.             int parent = index / 2;

    123.             //获取相应位置的数值
    124.             int parentValue = (Integer) heap.get(parent);
    125.             int indexValue = (Integer) heap.get(index);
    126.             //如果父亲节点比index的数值大,就交换二者的数值
    127.             if (parentValue > indexValue) {
    128.                 //交换数值
    129.                 swap(heap, parent, index);
    130.                 //递归调用
    131.                 heapUp(heap, parent);
    132.             }

    133.         }
    134.     }

    135.     //非递归实现
    136.     public static void heapUp2(List< Integer> heap, int index) {
    137.         int parent = 0;
    138.         for (; index > 1; index /= 2) {
    139.             //获取index的父节点的下标
    140.             parent = index / 2;

    141.             //获得父节点的值
    142.             int parentValue = (Integer) heap.get(parent);
    143.             //获得index位置的值
    144.             int indexValue = (Integer) heap.get(index);
    145.             
    146.             //如果大于就交换
    147.             if (parentValue > indexValue) {
    148.                 swap(heap, parent, index);
    149.             }
    150.         }
    151.     }
    152. }
    复制代码
    运行结果:
    D:java>java Heap
    0 2 1 10 3 7 5 15 17 20 9 15 8 16 11 -------------------------
    1 2 5 10 3 7 11 15 17 20 9 15 8 16
    D:java>javac Heap.java D:java>java Heap
    0 2 1 10 3 7 5 15 17 20 9 15 8 16 11
    -------------------------
    1 2 5 10 3 7 11 15 17 20 9 15 8 16

       
         
         
          
          

            
          

            
          
         
       

      


    源码下载:http://file.javaxxz.com/2014/12/4/000804078.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 04:27 , Processed in 0.352144 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表