一棵C#写的树(1)

       C#的确是一个很好的面向对象语言,我看《数据结构(第二版)》那本书应该出本用C#描述的版本。下面是我用C#写的一棵树。先用接口把节点做了抽象定义,这样在实现遍历,插入等操作的时候只对接口进行操作。在程序中,我尽量使用C#的特性,如接口,属性,玫举,这样代码虽然看起来比较冗长,但是,当代码越来越长的时候,你就会从中看到优点,因为合理的结构让你永远思路清晰。这课树我只能算写了一个开头,因为如果要把所有类型的树和加在他们之上的算法都写出来,我看没有1~2k 行程序是绝对不行的,不过,只要有时间,我一定会继续写的,同时希望大家也写,把这个代码库完善起来。
using System;
using System.Collections;
///
/// author 何潇(sailer)( he_x@263.net )
///
namespace Tree
{
 /// <summary>
 /// LEFT左子树,RIGHT右子树
 /// </summary>
 enum Position{LEFT,RIGHT};
 /// <summary>
 /// LINK指向孩子,THREAD指向后继
 /// </summary>
 enum Tag{LINK,THREAD};
 /// <summary>
 /// 二叉树节点的抽象定义
 /// </summary>
 interface IBinNode
 {
  bool isLeaf();
  object Element{get;set;}
  IBinNode Left{get;set;}
  IBinNode Right{get;set;}
 }

 /// <summary>
 /// 遍历,线索化等操作的接口
 /// </summary>
 interface ITravelBinTree
 {
  void PreOrderTravel();
  void InOrderTravel();
  void RevOrderTravel();
  void Print(IBinNode t);
 }
 interface IInsertBinTree
 {
  void Insert(IBinNode node,Position pos);
 }
 /// <summary>
 /// Normal actualize of bintree
 /// </summary>
 class BinNodePtr : IBinNode
 {
  protected object element;
  protected IBinNode lchild;
  protected IBinNode rchild;
  public BinNodePtr(object e,IBinNode left,IBinNode right)
  {
   element = e;
   lchild = left;
   rchild = right;
  }
  public BinNodePtr(object e)
  {
   element = e;
   lchild = rchild = null;
  }
  public BinNodePtr()
  {
   element = null;
   lchild = rchild =null;
  }
  public bool isLeaf()
  { 
   if(lchild==null && rchild==null)
    return true;
   return false;
  }
  public object Element
  {
   get{return element;}
   set{element = value;}
  }
  public IBinNode Left
  {
   get
   {
    return lchild;
   }
   set
   {
    lchild = value;
   }
  }
  public IBinNode Right
  {
   get
   {
    return rchild;
   }
   set
   {
    rchild = value;
   }
  }
 }
 class BinNodeLine : BinNodePtr,IBinNode
 {
  private Tag ltag,rtag;
  public BinNodeLine(object e,IBinNode left,IBinNode right) :base(e,left,right)
  {ltag = rtag = Tag.LINK;}
  public BinNodeLine(object e) : base(e)
  {ltag = rtag = Tag.LINK;}
  public Tag LTag
  {
   get{return ltag;}
   set{ltag = value;}
  }
  public Tag RTag
  {
   get{return rtag;}
   set{rtag = value;}
  }
 }
 class TravelBinTree : ITravelBinTree,IInsertBinTree
 {
  const int INIT_TREE_SIZE=20;
  private IBinNode tree;
  private BinNodeLine head; //线索化后的头指针
  private IBinNode prenode; //指向最近访问过的前驱节点
  public TravelBinTree()
  {
   tree = new BinNodePtr();
  }
  public TravelBinTree(IBinNode INode)
  {
   tree = INode;
  }
  /// <summary>
  /// 先序遍历树,用非递归算法实现
  /// </summary>
  /// <remarks>非递归实现</remarks>
  public void PreOrderTravel()
  {
   IBinNode temptree;
   Stack stk = new Stack(INIT_TREE_SIZE);
   if(tree == null)
    throw(new InvalidOperationException("访问的树为空"));
   temptree = tree;
   stk.Push(tree);
   while(stk.Count!=0)
   {
    while(temptree!=null)
    {
     Print(temptree);
     stk.Push(temptree.Left);
     temptree = temptree.Left;
    }
    stk.Pop(); // 空指针退栈
    if(stk.Count != 0)
    {
     temptree=(IBinNode)stk.Pop();
     stk.Push(temptree.Right);
     temptree = temptree.Right;
    }
   }
  }
  public void InOrderTravel()
  {
   InOrderTravel(tree);
  }
  private void InOrderTravel(IBinNode t)
  {
   if(t==null) return;
   InOrderTravel(t.Left);
   Print(t);
   InOrderTravel(t.Right);
  }
  public void RevOrderTravel()
  {
   RevOrderTravel(tree);
  }
  private void RevOrderTravel(IBinNode t)
  {
   if(t==null) return;
   RevOrderTravel(t.Left);
   RevOrderTravel(t.Right);
   Print(t);
  }
  public void Print(IBinNode t)
  {
   Console.Write(t.Element + ",");
  }
  public void Insert(IBinNode node,Position pos)
  {
   if(node == null)
    throw(new InvalidOperationException("不能将空节点插入树"));
   switch(pos)
   {
    case Position.LEFT : tree.Left = node;break;
    case Position.RIGHT: tree.Right = node;break;
   }
  }
  /// <summary>
  /// 按照先序遍历顺序遍历树
  /// </summary>
  public void TreeBuilder()
  {
   Stack stk = new Stack(INIT_TREE_SIZE);
   stk.Push(tree);
   Position pos;
   string para;
   pos = Position.LEFT;
   IBinNode baby,temp;
   while(true)
   {
    para = Console.ReadLine();
    if(para == "")
    {
     if(pos == Position.RIGHT)
     {
      stk.Pop();
      while(stk.Count!=0 && ((IBinNode)stk.Peek()).Right!=null)
       stk.Pop();
      if(stk.Count ==0) break;
     }
     else
      pos = Position.RIGHT;
    }
    else
    {
     if(tree.GetType().Equals()==true)
      baby = new BinNodePtr(para);
     temp = (IBinNode)stk.Peek();
     if(pos == Position.LEFT)
      temp.Left = baby;
     else
      temp.Right = baby;
     pos = Position.LEFT;
     stk.Push(baby);
    }
   }

  }
  /// <summary>
  /// 中序线索化
  /// </summary>
  public void InOrderThreading()
  {
   head = new BinNodeLine("");
   head.RTag = Tag.THREAD;
   head.Right = head;
   if(tree == null) head.Left = head;
   else
   {
    head.Left = tree; prenode = head;

   }
  }
  /// <summary>
  /// 中序线索化的递归实现
  /// </summary>
  /// <param name="t"></param>
  private void InThreading(IBinNode t)
  {
   if(t==null) 
    return;
   else
   {
    InThreading(t.Left);
   // if(left
   }
  }
 }
 /// <summary>
 /// Summary description for Class1.
 /// </summary>
 class Class1
 {
  /// <summary>
  /// 测试控制台
  /// </summary>
  /// <param name="args"></param>
  static void Main(string[] args)
  {
   string para = null;
   para = Console.ReadLine();
   BinNodePtr root = new BinNodePtr(para);
   TravelBinTree t = new TravelBinTree(root);
   t.TreeBuilder();
   t.PreOrderTravel();
   Console.WriteLine("");
   t.InOrderTravel();
   Console.WriteLine("");
   t.RevOrderTravel();
  }
 }
}

非常希望和大家交流( he_x@263.net )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的C#八叉算法的示例代码: ```csharp using System.Collections.Generic; public class Octree { private const int MAX_DEPTH = 10; private readonly int depth; private readonly float size; private readonly Vector3 center; private Octree[] children; private List<Vector3> points; public Octree(Vector3 center, float size, int depth = 0) { this.center = center; this.size = size; this.depth = depth; this.children = null; this.points = new List<Vector3>(); } public void Insert(Vector3 point) { if (depth == MAX_DEPTH) { points.Add(point); return; } if (children == null) { Split(); } int index = GetChildIndex(point); children[index].Insert(point); } public List<Vector3> GetPointsInRadius(Vector3 center, float radius) { List<Vector3> result = new List<Vector3>(); if (Vector3.Distance(center, this.center) <= radius + size / 2) { foreach (Vector3 point in points) { if (Vector3.Distance(center, point) <= radius) { result.Add(point); } } if (children != null) { for (int i = 0; i < 8; i++) { result.AddRange(children[i].GetPointsInRadius(center, radius)); } } } return result; } private void Split() { children = new Octree[8]; float childSize = size / 2; int childDepth = depth + 1; Vector3 childCenter; for (int i = 0; i < 8; i++) { childCenter = center + new Vector3( ((i & 1) == 1) ? childSize / 2 : -childSize / 2, ((i & 2) == 2) ? childSize / 2 : -childSize / 2, ((i & 4) == 4) ? childSize / 2 : -childSize / 2 ); children[i] = new Octree(childCenter, childSize, childDepth); } } private int GetChildIndex(Vector3 point) { int index = 0; if (point.x >= center.x) index |= 1; if (point.y >= center.y) index |= 2; if (point.z >= center.z) index |= 4; return index; } } ``` 这是一个基本的八叉实现,它可以插入和查找点,并且可以查找给定半径内的所有点。请注意,该示例中的向量使用Unity的Vector3类,如果你在其他环境中使用此代码,则需要更改向量类。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值