线段树-入门

来源:互联网 发布:成吉思汗征服月球知乎 编辑:程序博客网 时间:2024/04/29 03:13
Java代码 复制代码 收藏代码
  1. /**
  2. * 线段树入门
  3. * 问题:已知线段[2,5] [4,6] [0,7];求点2,4,7分别出现了多少次
  4. * 以下代码建立的线段树用链表来保存,且树的叶子结点类似[i,i]
  5. *
  6. * 参考链接:http://hi.baidu.com/semluhiigubbqvq/item/be736a33a8864789f4e4ad18
  7. * @author lijinnan
  8. */
  9. public class SegmentTreeLearn {
  10. public static void main(String[] args) {
  11. SegmentTree tree = new SegmentTree(0,7);
  12. int[][] segments = {
  13. {2, 5},
  14. {4, 6},
  15. {0, 7}
  16. };
  17. int[] targets = {2, 4, 7};
  18. for (int i = 0, len = segments.length; i < len; i++) {
  19. int[] segment = segments[i];
  20. tree.insert(segment[0], segment[1]);
  21. }
  22. for(int target : targets) {
  23. System.out.println(target + ":" + tree.caculateExistingTimes(target));
  24. }
  25. }
  26. }
  27. class SegmentTree {
  28. //递归定义的,因此很多操作都是递归实现
  29. private class Segment {
  30. int left;
  31. int right;
  32. int count;
  33. Segment leftChild;
  34. Segment rightChild;
  35. }
  36. private Segment root;
  37. public SegmentTree (int left,int right) {
  38. root = new Segment();
  39. build(root, left, right);
  40. }
  41. public void insert(int left,int right) {
  42. insert(root, left, right);
  43. }
  44. public int caculateExistingTimes(int target) {
  45. return caculateExistingTimes(root, target);
  46. }
  47. //从根节点开始查找叶子结点[target, target],对经过的节点的count求和
  48. private int caculateExistingTimes(Segment root,int target) {
  49. int result = 0;
  50. while( root.left != root.right) {
  51. int rootMid = root.left + (root.right - root.left) /2;
  52. result += root.count;
  53. if (target <= rootMid) {
  54. root = root.leftChild;
  55. } else if (target > rootMid) {
  56. root = root.rightChild;
  57. }
  58. }
  59. return result;
  60. }   
原创粉丝点击