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 )
|