tree234树的算法实现

        在数学上tree234 树和 红黑树是等价的,所以tree234树可以做为研究红黑树算法的辅助,因为从算法层面和理解层面红黑树要比tree234复杂
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. namespace HBDiscover.DSObj.Tree234
  5. {
  6.     /// <summary>
  7.     /// 数据项类
  8.     /// </summary>
  9.    public class DataItem
  10.     {
  11.         private long _data;
  12.         public DataItem(long data) 
  13.         {
  14.             _data = data;
  15.         }
  16.         public long Data
  17.         {
  18.             get { return _data; }
  19.             set { _data = value; }
  20.         }
  21.     }
  22.     public class Node
  23.     {
  24.         private const int CONST_ORDER = 4;
  25.         private int _itemNums;
  26.         private Node _parent;
  27.         private Node[] childNodes = new Node[CONST_ORDER];
  28.         private DataItem[] items = new DataItem[CONST_ORDER - 1];
  29.         /// <summary>
  30.         /// 是否是叶节点
  31.         /// </summary>
  32.         public bool IsLeaf
  33.         {
  34.             get { return childNodes[0]==null; }           
  35.         }
  36.         /// <summary>
  37.         /// 节点数据是否已满
  38.         /// </summary>
  39.         public bool IsFull
  40.         {
  41.             get { return _itemNums == CONST_ORDER - 1; }
  42.         }
  43.         /// <summary>
  44.         /// 已存在数据项数
  45.         /// </summary>
  46.         public int ItemNums
  47.         {
  48.             get { return _itemNums; }
  49.             set { _itemNums = value; }
  50.         }
  51.         public Node ParentNode
  52.         {
  53.             get { return _parent; }
  54.             set { _parent = value; }
  55.         }
  56.         /// <summary>
  57.         /// 数据项
  58.         /// </summary>
  59.         public DataItem[] DataItems
  60.         {
  61.             get { return items; }
  62.         }
  63.         /// <summary>
  64.         /// 子节点
  65.         /// </summary>
  66.         public Node[] Child
  67.         {
  68.             get { return childNodes; }
  69.         }
  70.         /// <summary>
  71.         /// 关联节点与当前节点的父子关系
  72.         /// </summary>
  73.         /// <param name="index"></param>
  74.         /// <param name="node"></param>
  75.         public void ConnectChild(int index, Node node)
  76.         {
  77.             childNodes[index] = node;
  78.             if(node!=null)
  79.                 node.ParentNode = this;
  80.         }
  81.         
  82.         /// <summary>
  83.         /// 断开与当前节点的父子关系
  84.         /// </summary>
  85.         /// <param name="index"></param>
  86.         /// <param name="node"></param>
  87.         /// <returns></returns>
  88.         public Node DisConnectChild(int index)
  89.         {
  90.             Node tempNode = childNodes[index];
  91.             if(tempNode!=null)
  92.                 tempNode.ParentNode = null;
  93.             return tempNode;
  94.         }
  95.         public int FindItem(long data)
  96.         {
  97.             for (int i = 0; i < CONST_ORDER - 1;i++)
  98.             {
  99.                 if (DataItems[i] == null)
  100.                     break;
  101.                 else if (data == DataItems[i].Data)
  102.                     return i;
  103.             }
  104.             return -1;
  105.         }
  106.         public int InsertItem(long data)
  107.         {
  108.             DataItem item = new DataItem(data);
  109.             return InsertItem(item);
  110.         }
  111.         public int InsertItem(DataItem newItem)
  112.         {
  113.             this.ItemNums++;
  114.             long newData = newItem.Data;
  115.             /*--------- 从中间数据2项开始比较--------*/
  116.             for (int i = CONST_ORDER - 3; i >= 0; i--)
  117.             {
  118.                 if (DataItems[i] == null)
  119.                     continue;
  120.                 else
  121.                 {
  122.                     if (newData < DataItems[i].Data)
  123.                     {
  124.                         DataItems[i + 1] = DataItems[i];
  125.                     }
  126.                     else
  127.                     {
  128.                         DataItems[i+1] = newItem;
  129.                         return i + 1;
  130.                     }
  131.                 }
  132.             }
  133.             DataItems[0] = newItem;
  134.             return 0;
  135.         }
  136.         public DataItem RemoveItem()
  137.         {
  138.             DataItem temp = this.items[this.ItemNums - 1];
  139.             this.items[this.ItemNums - 1] = null;
  140.             this.ItemNums--;
  141.             return temp;
  142.         }
  143.         public override string ToString()
  144.         {
  145.             string str = string.Empty;
  146.             for(int i=0;i<this._itemNums;i++)
  147.             {
  148.                 str += this.DataItems[i].Data.ToString();
  149.                 str += ",";
  150.             }
  151.             return str;
  152.         }
  153.     }
  154.     public class Tree234
  155.     {
  156.         private Node root = new Node();
  157.         public void Insert(long data)
  158.         {
  159.             Node curNode = root;
  160.             while (true)
  161.             {
  162.                 if (curNode.IsFull)
  163.                 {
  164.                     Split(curNode);
  165.                     curNode = curNode.ParentNode;//向上回朔
  166.                     curNode = GetAvailableChild(curNode, data);
  167.                 }
  168.                 else if (curNode.IsLeaf)
  169.                     break;
  170.                 else //中继节点不是叶节点数据项也没有满
  171.                     curNode = GetAvailableChild(curNode, data);
  172.             }
  173.             curNode.InsertItem(data);
  174.         }
  175.         /// <summary>
  176.         /// 找到当前值所在的节点(可能向下找)
  177.         /// </summary>
  178.         /// <param name="data"></param>
  179.         /// <returns></returns>
  180.         public Node Find(long data)
  181.         {
  182.             Node curNode = root;
  183.             while (true)
  184.             {
  185.                 if (curNode.FindItem(data) != -1)
  186.                     return curNode;
  187.                 else if (curNode.IsLeaf)
  188.                 {
  189.                     return null;
  190.                 }
  191.                 else
  192.                     curNode = GetAvailableChild(curNode, data);
  193.             }
  194.         }
  195.         /*  
  196.          *       1,2,3           2
  197.          *                  1(c0)|3(c1)  
  198.          */
  199.         /// <summary>
  200.         /// 分列节点 
  201.         /// </summary>
  202.         /// <param name="node"></param>
  203.         private void Split(Node node)
  204.         {
  205.             DataItem itemB, itemC;
  206.             Node parent, child1, child2;
  207.             itemC = node.RemoveItem();
  208.             itemB = node.RemoveItem();
  209.             child1 = node.DisConnectChild(2);
  210.             child2 = node.DisConnectChild(3);
  211.             /*-------------------- 左陔子操作-----------------*/
  212.             if (node == root)
  213.             {
  214.                 root = new Node();
  215.                 parent = root;
  216.                 parent.ConnectChild(0, node);
  217.             }
  218.             else
  219.             {
  220.                 parent = node.ParentNode;
  221.             }
  222.             /*---------------- 给插入点的孩子节点腾地---------*/
  223.             int index = parent.InsertItem(itemB);
  224.             for (int i = parent.ItemNums - 1; i > index; i--)
  225.             {
  226.                 parent.Child[i + 1] = parent.Child[i];
  227.             }
  228.             /*-------------------- 插入右孩子-----------------*/
  229.             Node newRightNode = new Node();
  230.             newRightNode.InsertItem(itemC);
  231.             parent.ConnectChild(index+1, newRightNode);
  232.             newRightNode.ConnectChild(0, child1);
  233.             newRightNode.ConnectChild(1, child2);
  234.         }
  235.         /// <summary>
  236.         /// 找到符合给定数据的子孩子(数据在孩子节点中)
  237.         /// </summary>
  238.         /// <param name="theNode"></param>
  239.         /// <param name="data"></param>
  240.         /// <returns></returns>
  241.         private static Node GetAvailableChild(Node theNode, long data)
  242.         {
  243.             int i;
  244.             for (i = 0; i < theNode.ItemNums; i++)
  245.             {
  246.                 if (data < theNode.DataItems[i].Data)
  247.                     return theNode.Child[i];
  248.             }
  249.             return theNode.Child[i];
  250.         }
  251.         string strDis = string.Empty;
  252.         private string ToString(Node node, int level, int childNum)
  253.         {
  254.             strDis += "level:" + level.ToString() + ";childnumat:" + childNum.ToString();
  255.             strDis += "|" + node.ToString() + "/r/n";
  256.             for (int i = 0; i < node.ItemNums + 1; i++)
  257.             {
  258.                 Node temp = node.Child[i];
  259.                 if (temp != null)
  260.                     ToString(temp, level + 1, i);
  261.             }
  262.             return strDis;
  263.         }
  264.         public override string ToString()
  265.         {
  266.             return ToString(root,0,0);
  267.         }
  268.     }
  269. }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值