在数学上tree234 树和 红黑树是等价的,所以tree234树可以做为研究红黑树算法的辅助,因为从算法层面和理解层面红黑树要比tree234复杂
- using System;
- using System.Collections.Generic;
- using System.Text;
- namespace HBDiscover.DSObj.Tree234
- {
- /// <summary>
- /// 数据项类
- /// </summary>
- public class DataItem
- {
- private long _data;
- public DataItem(long data)
- {
- _data = data;
- }
- public long Data
- {
- get { return _data; }
- set { _data = value; }
- }
- }
- public class Node
- {
- private const int CONST_ORDER = 4;
- private int _itemNums;
- private Node _parent;
- private Node[] childNodes = new Node[CONST_ORDER];
- private DataItem[] items = new DataItem[CONST_ORDER - 1];
- /// <summary>
- /// 是否是叶节点
- /// </summary>
- public bool IsLeaf
- {
- get { return childNodes[0]==null; }
- }
- /// <summary>
- /// 节点数据是否已满
- /// </summary>
- public bool IsFull
- {
- get { return _itemNums == CONST_ORDER - 1; }
- }
- /// <summary>
- /// 已存在数据项数
- /// </summary>
- public int ItemNums
- {
- get { return _itemNums; }
- set { _itemNums = value; }
- }
- public Node ParentNode
- {
- get { return _parent; }
- set { _parent = value; }
- }
- /// <summary>
- /// 数据项
- /// </summary>
- public DataItem[] DataItems
- {
- get { return items; }
- }
- /// <summary>
- /// 子节点
- /// </summary>
- public Node[] Child
- {
- get { return childNodes; }
- }
- /// <summary>
- /// 关联节点与当前节点的父子关系
- /// </summary>
- /// <param name="index"></param>
- /// <param name="node"></param>
- public void ConnectChild(int index, Node node)
- {
- childNodes[index] = node;
- if(node!=null)
- node.ParentNode = this;
- }
- /// <summary>
- /// 断开与当前节点的父子关系
- /// </summary>
- /// <param name="index"></param>
- /// <param name="node"></param>
- /// <returns></returns>
- public Node DisConnectChild(int index)
- {
- Node tempNode = childNodes[index];
- if(tempNode!=null)
- tempNode.ParentNode = null;
- return tempNode;
- }
- public int FindItem(long data)
- {
- for (int i = 0; i < CONST_ORDER - 1;i++)
- {
- if (DataItems[i] == null)
- break;
- else if (data == DataItems[i].Data)
- return i;
- }
- return -1;
- }
- public int InsertItem(long data)
- {
- DataItem item = new DataItem(data);
- return InsertItem(item);
- }
- public int InsertItem(DataItem newItem)
- {
- this.ItemNums++;
- long newData = newItem.Data;
- /*--------- 从中间数据2项开始比较--------*/
- for (int i = CONST_ORDER - 3; i >= 0; i--)
- {
- if (DataItems[i] == null)
- continue;
- else
- {
- if (newData < DataItems[i].Data)
- {
- DataItems[i + 1] = DataItems[i];
- }
- else
- {
- DataItems[i+1] = newItem;
- return i + 1;
- }
- }
- }
- DataItems[0] = newItem;
- return 0;
- }
- public DataItem RemoveItem()
- {
- DataItem temp = this.items[this.ItemNums - 1];
- this.items[this.ItemNums - 1] = null;
- this.ItemNums--;
- return temp;
- }
- public override string ToString()
- {
- string str = string.Empty;
- for(int i=0;i<this._itemNums;i++)
- {
- str += this.DataItems[i].Data.ToString();
- str += ",";
- }
- return str;
- }
- }
- public class Tree234
- {
- private Node root = new Node();
- public void Insert(long data)
- {
- Node curNode = root;
- while (true)
- {
- if (curNode.IsFull)
- {
- Split(curNode);
- curNode = curNode.ParentNode;//向上回朔
- curNode = GetAvailableChild(curNode, data);
- }
- else if (curNode.IsLeaf)
- break;
- else //中继节点不是叶节点数据项也没有满
- curNode = GetAvailableChild(curNode, data);
- }
- curNode.InsertItem(data);
- }
- /// <summary>
- /// 找到当前值所在的节点(可能向下找)
- /// </summary>
- /// <param name="data"></param>
- /// <returns></returns>
- public Node Find(long data)
- {
- Node curNode = root;
- while (true)
- {
- if (curNode.FindItem(data) != -1)
- return curNode;
- else if (curNode.IsLeaf)
- {
- return null;
- }
- else
- curNode = GetAvailableChild(curNode, data);
- }
- }
- /*
- * 1,2,3 2
- * 1(c0)|3(c1)
- */
- /// <summary>
- /// 分列节点
- /// </summary>
- /// <param name="node"></param>
- private void Split(Node node)
- {
- DataItem itemB, itemC;
- Node parent, child1, child2;
- itemC = node.RemoveItem();
- itemB = node.RemoveItem();
- child1 = node.DisConnectChild(2);
- child2 = node.DisConnectChild(3);
- /*-------------------- 左陔子操作-----------------*/
- if (node == root)
- {
- root = new Node();
- parent = root;
- parent.ConnectChild(0, node);
- }
- else
- {
- parent = node.ParentNode;
- }
- /*---------------- 给插入点的孩子节点腾地---------*/
- int index = parent.InsertItem(itemB);
- for (int i = parent.ItemNums - 1; i > index; i--)
- {
- parent.Child[i + 1] = parent.Child[i];
- }
- /*-------------------- 插入右孩子-----------------*/
- Node newRightNode = new Node();
- newRightNode.InsertItem(itemC);
- parent.ConnectChild(index+1, newRightNode);
- newRightNode.ConnectChild(0, child1);
- newRightNode.ConnectChild(1, child2);
- }
- /// <summary>
- /// 找到符合给定数据的子孩子(数据在孩子节点中)
- /// </summary>
- /// <param name="theNode"></param>
- /// <param name="data"></param>
- /// <returns></returns>
- private static Node GetAvailableChild(Node theNode, long data)
- {
- int i;
- for (i = 0; i < theNode.ItemNums; i++)
- {
- if (data < theNode.DataItems[i].Data)
- return theNode.Child[i];
- }
- return theNode.Child[i];
- }
- string strDis = string.Empty;
- private string ToString(Node node, int level, int childNum)
- {
- strDis += "level:" + level.ToString() + ";childnumat:" + childNum.ToString();
- strDis += "|" + node.ToString() + "/r/n";
- for (int i = 0; i < node.ItemNums + 1; i++)
- {
- Node temp = node.Child[i];
- if (temp != null)
- ToString(temp, level + 1, i);
- }
- return strDis;
- }
- public override string ToString()
- {
- return ToString(root,0,0);
- }
- }
- }