1、数据结构与算法(C#实现)系列-前言Heavenkiller (原创)搞计算机的人都应该很清楚,语言只是一种工具,算法才是灵魂。现在的开发语言有很多,如 C+,VB,Perl,java,c#,还有如脚本语言 js,vbs 等,在如此多的选择面前,很多人不知道该选择哪一种好。其实不管哪一种语言,既然他存在,就一定有他的价值,有它的特定用途,而这往往是其它语言所无法比拟的。譬如 C+就适合于系统底层的编程,而 java一般就用于对稳定性,兼容性要求较高的场合,正所谓各有所长。像我一般用C+编写网络基层和与操作系统相关的程序,用 C#写 ASP.NET 等程序,必要的时候再辅以 Rose, Rati
2、onal XDE 等建模工具。但无论选择哪一种语言,算法才是根本,掌握了算法,就掌握了所有语言的根本,以不变应万变。微软的 C#是一种全新的语言,利用它能快捷、高效地布署程序。现在关于 C#的资料也已经有很多了,各个方面的资料都能找得到,但用 C#做数据结构的似乎还没有什么,在 CSDN上我只找到了三四篇,而且仅仅是讲了一下链表之类简单的数据结构。于是我利用空闲的时间用 C#写了一些数据结构与算法的实现,希望对大家学习数据结构能够有所帮助。另外,由于时间仓促,难免出现一些纰漏,希望大家不吝赐教给予指正,我的 email 是 .欢迎大家和我一起交流学习。本系列包括树,N 叉树,广义树,二叉树,B
3、ST 二叉查找树,AVL 平衡树,堆,二叉堆,以及图。还有一些如哈希表,散列,左翼树,二项树,Haffman 编码树等因时间关系,暂时未能奉上,以后有时间再补上吧。首先给大家展示一幅用Rational XDE for .NET 生成的类模型图,让大家对所有的类有一个大概的了解。数据结构与算法(C#实现)系列-演示篇(一)Heavenkiller(原创)这一篇主要是针对以后各篇的数据类型进行一个实质性的演示。因此希望大家具体看了各种数据结构的分析之后再看这篇。主要包括如下几个方面的演示:1. 堆栈。 演示了一个利用堆栈作的 RPN 计算器2. 排序表。演示了一个利用排序表做的多项式表达式的加法运
4、算3. 广义树。演示了深度遍历和广度遍历4. N 叉树。演示了 N 叉树的生成插入删除等基本操作5. 表达式树。演示了一个用二叉树和堆栈做的可以将一个后缀表达式翻译为日常中熟悉的中缀表达式的例子6. AVL 树。演示了基本操作using System;using System.Collections;namespace DataStructure/ / Class1 的摘要说明。/ class Show/ / 应用程序的主入口点。/ STAThreadstatic void Main(string args)/ TODO: 在此处添加代码以启动应用程序/while(true)Console.W
5、riteLine(“please choose a the No. of a item you want to perform:“);Console.WriteLine(“1.Stack- RPNCalCulator“);Console.WriteLine(“2.SortedList-the addition of polynomial realized by sortedlist “);Console.WriteLine(“3.GeneralTree-depthtravesal and breathtraval“);Console.WriteLine(“4.NaryTree“);Consol
6、e.WriteLine(“5.ExpressionTree“);Console.WriteLine(“6.AVLTree“);Console.WriteLine(“7.BinaryHeap“);Console.WriteLine(“exit-Exit this programme“);/Test();switch(Console.ReadLine()case “1“:/Show StackShowStack_RPNCalCulator();break;case “2“:/SortedListShowSortedList_Polynomial();break;case “3“: ShowGene
7、ralTree_travel();break;case “4“:ShowNaryTree();/演示一个三叉树的 Attach 和Detachbreak;case “5“:ShowExpressionTree();break;case “6“:ShowAVLTree();break;case “7“:ShowBinaryHeap();break;case “exit“:return; default:break;public static void ShowBinaryHeap()/构造一个二叉堆, 包含 2,4,6,8,10,12BinaryHeap bHeap=new BinaryHeap
8、(10);bHeap.Enqueue(12);bHeap.Enqueue(10);bHeap.Enqueue(8);bHeap.Enqueue(6);bHeap.Enqueue(4);bHeap.Enqueue(2);/测试 Dequeue();while(bHeap.Count!=0)Console.WriteLine(bHeap.DequeueMin().ToString();public static void ShowAVLTree()AVLTree testAVL=new AVLTree(5);testAVL.Insert(1);testAVL.Insert(3);testAVL.I
9、nsert(7);testAVL.Insert(8);testAVL.Insert(9);testAVL.Insert(10);testAVL.Insert(11);PrintVisitor vis=new PrintVisitor();Tree.InOrder inVis=new DataStructure.Tree.InOrder(vis);testAVL.DepthFirstTraversal(inVis);public static void ShowExpressionTree()ExpressionTree.PostfixToInfix();public static void S
10、howNaryTree()/构造一个三叉树,具体见图 1-2NaryTree A=new NaryTree(3,“A“);NaryTree B=new NaryTree(3,“B“);NaryTree C=new NaryTree(3,“C“);NaryTree D=new NaryTree(3,“D“);NaryTree E=new NaryTree(3,“E“);B.AttachSubtree(1,D);B.AttachSubtree(2,E);A.AttachSubtree(1,B);A.AttachSubtree(3,C);/-Console.WriteLine(“广度遍历“);Pri
11、ntVisitor vis=new PrintVisitor();A.BreadthFirstTraversal(vis);/广度遍历Console.WriteLine(“前序遍历“);Tree.PreOrder preVisit=new DataStructure.Tree.PreOrder(vis);A.DepthFirstTraversal(preVisit);Console.WriteLine(“后序遍历“);Tree.PostOrder postVisit=new DataStructure.Tree.PostOrder(vis);A.DepthFirstTraversal(post
12、Visit);Console.WriteLine(“中序遍历“);Tree.InOrder inVisit=new DataStructure.Tree.InOrder(vis);A.DepthFirstTraversal(inVisit);数据结构与算法(C#实现) 系列- 演示篇( 二)Heavenkiller(原创)public static void ShowGeneralTree_travel()IEnumerator tmpIEnum;Tree.TraversalType travelType=0;/-提示-Console.WriteLine(“please choose a th
13、e No. of a item you want to travel:“);Console.WriteLine(“1.BreadthFirst- 广度遍历 “);Console.WriteLine(“2.PreDepthFirst-前序遍历“);Console.WriteLine(“3.InDepthFirst-中序遍历 “);Console.WriteLine(“4.PostDepthFirst-后序遍历“);switch(Console.ReadLine()case “1“:/Show StacktravelType=Tree.TraversalType.Breadth;Console.W
14、riteLine(“广度遍历“);break;case “2“:/SortedListtravelType=Tree.TraversalType.PreDepth;Console.WriteLine(“前序遍历“);break;case “3“:travelType=Tree.TraversalType.InDepth;Console.WriteLine(“中序遍历“);break;case “4“:travelType=Tree.TraversalType.PostDepth;Console.WriteLine(“后序遍历“);break;default:break;/构造一棵广义树 gen
15、eraltreeGeneralTree A=new GeneralTree(“A“);GeneralTree B=new GeneralTree(“B“);GeneralTree C=new GeneralTree(“C“);GeneralTree D=new GeneralTree(“D“);GeneralTree E=new GeneralTree(“E“);GeneralTree F=new GeneralTree(“F“);A.AttackSubtree(B);A.AttackSubtree(C);B.AttackSubtree(D);B.AttackSubtree(E);A.Atta
16、ckSubtree(F);/show the operationConsole.WriteLine(“A.AttackSubtree(B)“);Console.WriteLine(“A.AttackSubtree(C)“);Console.WriteLine(“B.AttackSubtree(D)“);Console.WriteLine(“B.AttackSubtree(E)“);Console.WriteLine(“A.AttackSubtree(F)“);/-A.SetTraversalType(travelType);/设置遍历类型tmpIEnum=A.GetEnumerator();/
17、Console.WriteLine(“begin to depthfist travel:“);while(tmpIEnum.MoveNext()Console.WriteLine(tmpIEnum.Current.ToString();public static void ShowStack_RPNCalCulator()/read a expression string and push every character into the stack in queue.Console.WriteLine(“this is performance for stack,you can input
18、 a string like this 123*+,then this subprogramme can compute it and get the result 7,this is RPN calculator. “);Console.WriteLine(“please input a expression string:“);string strExpression=Console.ReadLine();char tmpChars=strExpression.ToCharArray(0,strExpression.Length);Stack stackRPN=new Stack(); i
19、nt numA,numB;foreach(char tmp in tmpChars)switch (tmp)case *:numA=(int)stackRPN.Pop();numB=(int)stackRPN.Pop();stackRPN.Push(numA*numB);break;case +:numA=(int)stackRPN.Pop();numB=(int)stackRPN.Pop();stackRPN.Push(numA+numB);break;default:stackRPN.Push(Int32.Parse(tmp.ToString();break;Console.WriteLi
20、ne(“the result is:0“,stackRPN.Pop().ToString();数据结构与算法(C#实现) 系列- 演示篇( 三)Heavenkiller(原创)public static void ShowSortedList_Polynomial()/100+10*x+x2 + 1+10*x+100x2SortedList tmpListA=new SortedList();SortedList tmpListB=new SortedList();SortedList tmpListC=new SortedList();/used to store the resultSor
21、tedList tmpKeyList=new SortedList();/used to store all keys of two polynomials/init polynomial A and show ittmpListA.Add(0,100);tmpListA.Add(1,10);tmpListA.Add(2,1);ShowSortedList_ShowPolynomial(“tmpListA“,tmpListA.GetEnumerator();/init polynomial B and show ittmpListB.Add(0,1);tmpListB.Add(1,10);tm
22、pListB.Add(2,100);ShowSortedList_ShowPolynomial(“tmpListB“,tmpListB.GetEnumerator();/init the key list which contains all keys of A and B but everyone once IDictionaryEnumerator tmpIDic=tmpListA.GetEnumerator();while(tmpIDic.MoveNext()!=false)if(!tmpKeyList.ContainsKey(tmpIDic.Key)tmpKeyList.Add(tmp
23、IDic.Key,null);tmpIDic=tmpListB.GetEnumerator();while(tmpIDic.MoveNext()!=false)if(!tmpKeyList.ContainsKey(tmpIDic.Key)tmpKeyList.Add(tmpIDic.Key,null);/Add A and B and show the resulttmpIDic=tmpKeyList.GetEnumerator();while(tmpIDic.MoveNext()!=false)object objA=null,objB=null,objC=null;objC=tmpIDic
24、.Key;if(tmpListA.ContainsKey(objC)objA=tmpListAobjC;if(tmpListA.ContainsKey(objC)objB=tmpListBobjC;/objC=objA+objB;/tmpKeyListobjC=(int)objA+(int)objC;tmpListC.Add(objC,(int)objA+(int)objB);ShowSortedList_ShowPolynomial(“the addition result of A and B“,tmpListC.GetEnumerator();public static void Sho
25、wSortedList_ShowPolynomial(string tip,IDictionaryEnumerator iDic)string strExpress=null;iDic.Reset();while(iDic.MoveNext()!=false)strExpress+=iDic.Value.ToString()+“*X“+iDic.Key.ToString()+“+“;Console.WriteLine(tip+“:“+strExpress);数据结构与算法(C#实现) 系列- 树( 一)Heavenkiller(原创)首先我们给树下一个定义:树是一个有限的、非空的结点集,T=r
26、 or T1 or T2 oror Tn它具有下列性质:1集合指定的结点 r 叫做树的根结点2其余的结点可以划分成n 个子集,T1,T2,Tn(n=0),其中每一个子集都是一棵树。树的其它定义如度,叶子,高等就请大家查阅别的资料吧,到处都有的。树的主要性质一个就是遍历,分为深度遍历和广度遍历在这里分别实现为 DepthFirstTravesal()和 WidthFirstTravesal()其中深度遍历又分为前序遍历、中序遍历、和后序遍历这是是采用适配器技术实现的。using System;using System.Collections;namespace DataStructure/ /
27、Tree 的摘要说明。/ when traverse, traversaltype cant be changed,or throw a exception/ 支持枚举、比较、深度复制/ public abstract class Tree:IEnumerable,IComparablepublic Tree()/ TODO: 在此处添加构造函数逻辑/protected Queue keyqueue=new Queue();/仅仅用于枚举时存放数据,不参与 Equals 实现中的比较protected TraversalType traversaltype=TraversalType.Brea
28、dth;/ choose a traversal type,and DepthFirst is default/protected uint degree=0;/degree of the tree, init it as 0/protected uint height=0;/height of the tree, init it as 0/枚举不同的遍历类型public enum TraversalTypeBreadth=1,/广度遍历PreDepth=2,/前序遍历InDepth=3,/中序遍历PostDepth=4/后序遍历;/public virtual abstract object
29、 Keypublic abstract Tree thisuint _indexget;set;/if I only use get, can I change it later?public abstract object Keyget;public abstract uint Degreeget;/public abstract uint Heightget;public void SetTraversalType(TraversalType _type)traversaltype=_type;/set a traversal a type, if its not set manually
30、, DepthFirst will be chosen in defaultpublic abstract bool IsEmpty();/ property takes the place of IsEmpty()public abstract bool IsLeaf();/Only Visit, neednt queuepublic virtual void DepthFirstTraversal(IPrePostVisitor _vis)/middle depthfirst traversal/通过_vis 使用不同的访问者来进行前序、后序、中序遍历if(!IsEmpty()_vis.P
31、reVisit(this.Key);if( this.Degree=1 )if( this.Degree=2)for(uint i=0;i/ GeneralTree 的摘要说明 。/ general tree is a tree which has a arbitrary degree and no empty tree/ use ArrayList to replace ListAsLinkedList / public class GeneralTree:Treeprotected object key=null;protected uint degree=0;/protected uin
32、t height=0;protected ArrayList treeList=new ArrayList();public GeneralTree(object _objKey)/ TODO: 在此处添加构造函数逻辑/key=_objKey;degree=0;/height=0;ArrayList treeList=new ArrayList();public virtual void AttackSubtree(GeneralTree _gTree)this.treeList.Add(_gTree);+degree;public virtual GeneralTree DetachSubt
33、ree(GeneralTree _gTree)this.treeList.Remove(_gTree);degree-;return _gTree;/? how to remove ,reference or object?public override Tree thisuint _indexgetif(_index=this.degree)throw new Exception(“my:out of index“);return (Tree)treeList(int)_index;settreeList(int)_index=value;数据结构与算法(C#实现) 系列- 广义树( 二)H
34、eavenkiller(原创)public override object Keygetreturn this.key;public override uint Degreegetreturn this.degree;/public override uint Heightgetreturn this.height;public override bool IsEmpty()/ property takes the place of IsEmpty()return false;/generaltree wont be empty for everpublic override bool IsL
35、eaf()return this.degree=0;/if this trees degree is zero, it means the tree has no subtrees, so it is leaf certainly/overwrite Object.Equals() - reference type realizationpublic override bool Equals(object _obj)if( !base.Equals(_obj) )return false;/基类比较不相等,则不相等/基类中的一些条目在此可免去/在基类中已判定其为 GeneralTree类型,故
36、转型不会失败GeneralTree tmpTree=(GeneralTree)_obj;/比较引用成员if( !Object.Equals(this.treeList,tmpTree.treeList) )return false; /比较值类型成员return true;数据结构与算法(C#实现) 系列-N 叉树( 一)Heavenkiller(原创)N 叉树的每一节点度数都相同,为 Nusing System;using System.Collections;namespace DataStructure/ / NaryTree 的摘要说明 。-N 叉树/ public class Nar
37、yTree:Tree/ member variablesprotected object key;protected uint degree;protected ArrayList treeList=new ArrayList();/protected uint height=0;/暂时默认为0/create an empty tree whose attribute of degree is _degreepublic NaryTree(uint _degree)/ TODO: 在此处添加构造函数逻辑/this.key=null;this.degree=_degree;this.treeLi
38、st=null;/构造一棵叶子结点的 N叉树public NaryTree(uint _degree,object _key)this.key=_key;this.degree=_degree;this.treeList=new ArrayList();this.treeList.Capacity=(int)_degree;for(int i=0;i=this.degree )throw new Exception(“My:out of index!“);/如果出界,则抛出异常if( this.IsEmpty() )return null;/如果是空树,则索引器返 回一个 nullreturn
39、 (Tree)this.treeList(int)_index;setthis.treeList(int)_index=value;数据结构与算法(C#实现) 系列-N 叉树( 二)Heavenkiller(原创)public override uint Degreegetreturn this.degree;/- /只用于空树结点public virtual void AttachKey(object _obj)if(!IsEmpty()throw new Exception(“My:this node must be a empty tree node!“);this.key=_obj;t
40、his.treeList=new ArrayList();/产生一个 degree长的数组,并将其初始化为空树this.treeList.Capacity=(int)this.degree;for(int i=0;i/ AVLTree 的摘要说明。-平衡二叉查找树/ public class AVLTree:BSTprotected int height;/空树的高定义为-1;/构造一棵空的二叉查找树public AVLTree():base()/ TODO: 在此处添加构造函数逻辑/height=-1;public AVLTree(object _obj):base(_obj)height=
41、0;/-protected override object GetEmptyInstance(uint _degree) return new AVLTree(); /-protected int BalanceFactor()if (this.IsEmpty() )return 0;return (AVLTree)this.Left).height-(AVLTree)this.Right).height;/调整高度protected void AdjustHeight() this.height=Math.Max( (AVLTree)this.Left).height, (AVLTree)t
42、his.Right).height)+1; /平衡时的四种旋转方式protected void LLRotation()if( this.IsEmpty() )throw new Exception(“My:invalid operation!“);AVLTree avlB=new AVLTree(this.key);avlB.AttachSubtree(1,(AVLTree)this01);avlB.AttachSubtree(2,(AVLTree)this1);this.key=this0.Key;this0=this00;this1=avlB;/调整两个节点的高度(AVLTree)thi
43、s.Right).AdjustHeight();this.AdjustHeight();protected void LRRotation()if( this.IsEmpty() )throw new Exception(“My:invalid operation!“);(AVLTree)this.Left).RRRotation();this.LLRotation();protected void RRRotation()if( this.IsEmpty() )throw new Exception(“My:invalid operation!“);AVLTree avlB=new AVLT
44、ree(this.key); avlB.AttachSubtree(1,(AVLTree)this0);avlB.AttachSubtree(2,(AVLTree)this10);/avlA.AttachSubtree(1,avlB);/this=avlA;this.key=this1.Key;this0=avlB;this1=this11;/调整两个节点的高度(AVLTree)this.Left).AdjustHeight();this.AdjustHeight();protected void RLRotation()if( this.IsEmpty() )throw new Except
45、ion(“My:invalid operation!“);(AVLTree)this.Right).LLRotation();this.RRRotation();数据结构与算法(C#实现)系列-AVLTree (二)/-override-public override void AttachKey(object _obj)if(!IsEmpty()throw new Exception(“My:this node must be a empty tree node!“);this.key=_obj;/产生一个 degree长的数组,并将其初始化为空树this.treeList=new Arra
46、yList();this.treeList.Capacity=(int)this.degree;for(int i=0;i1)if(this.BalanceFactor()0)if (AVLTree)this.Left).BalanceFactor()0)this.LLRotation();elsethis.LRRotation();elseif (AVLTree)this.Right).BalanceFactor()/ BinaryTree 的摘要说明。/ public class BinaryTree:NaryTree/构造二叉空树public BinaryTree():base(2)/ TODO: 在此处添加构造函数逻辑/public BinaryTree(object _obj):base(2,_obj)/-protected override object GetEmptyInstance(uint _degree) return new BinaryTree(_degree); /-