/// <summary> /// 创建一颗二插排序树 /// </summary> /// <param name="tree"></param> /// <param name="arr"></param> public static void CreateBiSortTree(BiTree <int> tree, int[] arr) { foreach (var t in arr) { BiSortTreeInsert(tree, t); } }
/// <summary> /// 二叉排序树查找 /// 实现思路: /// 从根节点开始遍历,如果正好该根节点就是要找的值,则返回true,如果要查找的值比根节点大,则调整到右子树查找,反之调整到左子树。 /// </summary> /// <param name="bTree"></param> /// <param name="key"></param> /// <returns></returns> public static bool BiSortTreeSearch(BiTree <int> bTree, int key) { Node <int> p; //如果树为空,则直接返回-1 if (bTree.IsEmpty()) { return(false); } p = bTree.Root; while (p != null) { //如果根节点就是要找的 if (p.Data == key) { return(true); } else if (key > p.Data) { //调整到右子树 p = p.RChild; } else { //调整到左子树 p = p.LChild; } } return(false); }
static void Test(string[] args) { #region 二叉树 BiTree <string> tree = new BiTree <string>("A"); Node <string> root = tree.Root; tree.InsertL("B", root); tree.InsertR("C", root); Node <string> b = root.LChild; Node <string> c = root.RChild; tree.InsertL("D", b); tree.InsertR("E", b); tree.InsertL("F", c); tree.InsertR("G", c); Node <string> d = b.LChild; Node <string> e = b.RChild; tree.InsertL("H", d); tree.InsertR("I", d); tree.InsertL("J", e); Console.WriteLine("前序遍历开始>>>\n"); //前序遍历 PreOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("中序遍历开始>>>\n"); //中序遍历 InOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("后序遍历开始>>>\n"); //后序遍历 PostOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("层序遍历开始>>>\n"); //后序遍历 LevelOrder(root); Console.Read(); #endregion }
/// <summary> /// 二插排序树的插入(即:先查找,如果找不到,则插入要查找的值) /// 逻辑:先在树中查找指定的值,如果找到,则不插入,如果找不到,则把要查找的值插入到最后一个节点下做为子节点(即:先查找,再插入) /// </summary> /// <param name="bTree"></param> /// <param name="key"></param> /// <returns></returns> public static bool BiSortTreeInsert(BiTree <int> bTree, int key) { Node <int> p = bTree.Root; Node <int> last = null;//用来保存查找过程中的最后一个节点 while (p != null) { if (p.Data == key) { return(true); } last = p; if (key > p.Data) { p = p.RChild; } else { p = p.LChild; } } //如果找了一圈,都找不到要找的节点,则将目标节点插入到最后一个节点下面 p = new Node <int>(key); if (last == null) { bTree.Root = p; } else if (p.Data < last.Data) { last.LChild = p; } else { last.RChild = p; } return(false); }
/// <summary> /// 删除二叉排序树的节点 /// 这也是动态查询的一种情况,找到需要的节点后,如果存在,则删除该节点。 /// 可以分为几下四种情况: /// a.待删除的节点,本身就是叶节点:这种情况下最简单,只要把这个节点删除掉,然后父节点的LChild或RChild设置为null即可 /// b.待删除的节点,只有左子树:将本节点的左子树上移,挂到父节点下的LChild,然后删除自身即可 /// c.待删除的节点,只有右子树:将自身节点的右子树挂到父节点的左子树,然后删除自身即可 /// d.待删除的节点,左、右子树都有:这个要复杂一些,先找出自身节点右子树中的左分支的最后一个节点(最小左节点),然后将它跟自身对调,同时将“最小左节点”下的分支上移。 /// </summary> /// <param name="tree"></param> /// <param name="key"></param> /// <returns></returns> public static bool DeleteBiSort(BiTree <int> tree, int key) { //二叉排序树为空 if (tree.IsEmpty()) { return(false); } Node <int> p = tree.Root; Node <int> parent = p; while (p != null) { if (p.Data == key) { if (tree.IsLeaf(p))//如果待删除的节点为叶节点 { #region if (p == tree.Root) { tree.Root = null; } else if (p == parent.LChild) { parent.LChild = null; } else { parent.RChild = null; } #endregion } else if ((p.RChild == null) && (p.LChild != null)) //仅有左分支 { #region if (p == parent.LChild) { parent.LChild = p.LChild; } else { parent.RChild = p.LChild; } #endregion } else if ((p.LChild == null) && (p.RChild != null)) //仅有右分支 { #region if (p == parent.LChild) { parent.LChild = p.RChild; } else { parent.RChild = p.RChild; } #endregion } else //左,右分支都有 { //原理:先找到本节点右子树中的最小节点(即右子树的最后一个左子节点) #region Node <int> q = p; Node <int> s = p.RChild; while (s.LChild != null) { q = s; s = s.LChild; } Console.WriteLine("s.Data=" + s.Data + ",p.Data=" + p.Data + ",q.Data=" + q.Data); //然后将找到的最小节点与自己对调(因为最小节点是从右子树中找到的,所以其值肯定比本身要大) p.Data = s.Data; if (q != p) { //将q节点原来的右子树挂左边(这样最后一个节点的子树就调整到位了) q.LChild = s.RChild; } else //s节点的父节点就是p时,将s节点原来的右树向上提(因为s已经换成p点的位置了,所以这个位置就不需要了,直接把它的右树向上提升即可) { q.RChild = s.RChild; } #endregion } return(true); } else if (key > p.Data) { parent = p; p = p.RChild; } else { parent = p; p = p.LChild; } } return(false); }
static void Main(string[] args) { #region 排列 // 求排列:5个数取3个的任意排列 //int[] IntArr = new int[] { 1, 2, 3, 4, 5 }; //整型数组 //List<int[]> ListCombination = PermutationAndCombination<int>.GetPermutation(IntArr, 3); //求全部的5取3排列 //foreach (int[] arr in ListCombination) //{ // foreach (int item in arr) // { // Console.Write(item + " "); // } // Console.WriteLine(""); //} #endregion #region 组合 // 求组合:求5个数里任意3个数的组合 //int[] IntArr = new int[] { 1, 2, 3, 4, 5 }; //整型数组 //List<int[]> ListCombination = PermutationAndCombination<int>.GetCombination(IntArr, 3); //求全部的3-3组合 //foreach (int[] arr in ListCombination) //{ // foreach (int item in arr) // { // Console.Write(item + " "); // } // Console.WriteLine(""); //} //Console.ReadKey(); #endregion #region 二叉树 BiTree <string> tree = new BiTree <string>("A"); Node <string> root = tree.Root; tree.InsertL("B", root); tree.InsertR("C", root); Node <string> b = root.LChild; Node <string> c = root.RChild; tree.InsertL("D", b); tree.InsertR("E", b); tree.InsertL("F", c); tree.InsertR("G", c); Node <string> d = b.LChild; Node <string> e = b.RChild; tree.InsertL("H", d); tree.InsertR("I", d); tree.InsertL("J", e); Console.WriteLine("前序遍历开始>>>\n"); //前序遍历 PreOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("中序遍历开始>>>\n"); //中序遍历 InOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("后序遍历开始>>>\n"); //后序遍历 PostOrder(root); Console.WriteLine("\n------------------------\n"); Console.WriteLine("层序遍历开始>>>\n"); //后序遍历 LevelOrder(root); Console.Read(); #endregion #region 顺序表 Console.WriteLine("顺序表测试开始..."); SeqList <string> seq = new SeqList <string>(10); seq.Append("x"); seq.InsertBefore("w", 0); seq.InsertBefore("v", 0); seq.Append("y"); seq.InsertBefore("z", seq.Count()); Console.WriteLine(seq.Count()); //5 Console.WriteLine(seq.ToString()); //v,w,x,y,z Console.WriteLine(seq[1]); //w Console.WriteLine(seq[0]); //v Console.WriteLine(seq[4]); //z Console.WriteLine(seq.IndexOf("z")); //4 Console.WriteLine(seq.RemoveAt(2)); //x Console.WriteLine(seq.ToString()); //v,w,y,z seq.InsertBefore("x", 2); Console.WriteLine(seq.ToString()); //v,w,x,y,z Console.WriteLine(seq.GetItemAt(2)); //x seq.Reverse(); Console.WriteLine(seq.ToString()); //z,y,x,w,v seq.InsertAfter("z_1", 0); seq.InsertAfter("y_1", 2); seq.InsertAfter("v_1", seq.Count() - 1); Console.WriteLine(seq.ToString());//z,z_1,y,y_1,x,w,v,v_1 #endregion #region 单链表 Console.WriteLine("-------------------------------------"); Console.WriteLine("单链表测试开始..."); LinkList <string> link = new LinkList <string>(); link.Head = new LinkNode <string>("x"); link.InsertBefore("w", 0); link.InsertBefore("v", 0); link.Append("y"); link.InsertBefore("z", link.Count()); Console.WriteLine(link.Count()); //5 Console.WriteLine(link.ToString()); //v,w,x,y,z Console.WriteLine(link[1]); //w Console.WriteLine(link[0]); //v Console.WriteLine(link[4]); //z Console.WriteLine(link.IndexOf("z")); //4 Console.WriteLine(link.RemoveAt(2)); //x Console.WriteLine(link.ToString()); //v,w,y,z link.InsertBefore("x", 2); Console.WriteLine(link.ToString()); //v,w,x,y,z Console.WriteLine(link.GetItemAt(2)); //x link.Reverse(); Console.WriteLine(link.ToString()); //z,y,x,w,v link.InsertAfter("1", 0); link.InsertAfter("2", 1); link.InsertAfter("6", 5); link.InsertAfter("8", 7); link.InsertAfter("A", 10); //Position is error! Console.WriteLine(link.ToString()); //z,1,2,y,x,w,6,v,8 #endregion #region 循环队列 CSeqQueue <int> queue = new CSeqQueue <int>(5); queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); queue.Enqueue(4); Console.WriteLine(queue); //front = -1 rear = 3 count = 4 data = 1,2,3,4 queue.Dequeue(); Console.WriteLine(queue); //front = 0 rear = 3 count = 3 data = 2,3,4 queue.Dequeue(); Console.WriteLine(queue); //front = 1 rear = 3 count = 2 data = 3,4 queue.Enqueue(5); Console.WriteLine(queue); //front = 1 rear = 4 count = 3 data = 3,4,5 queue.Enqueue(6); Console.WriteLine(queue); //front = 1 rear = 0 count = 4 data = 3,4,5,6 queue.Enqueue(7); //Queue is full Console.WriteLine(queue); //front = 1 rear = 0 count = 4 data = 3,4,5,6 queue.Dequeue(); queue.Enqueue(7); Console.WriteLine(queue);//front = 2 rear = 1 count = 4 data = 4,5,6,7 queue.Clear(); Console.WriteLine(queue);//queue is empty. queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); queue.Enqueue(4); Console.WriteLine(queue); //front = -1 rear = 3 count = 4 data = 1,2,3,4 queue.Enqueue(5); Console.WriteLine(queue); //front = -1 rear = 4 count = 5 data = 1,2,3,4,5 queue.Enqueue(6); //Queue is full Console.WriteLine(queue); //front = -1 rear = 4 count = 5 data = 1,2,3,4,5 queue.Dequeue(); queue.Dequeue(); queue.Dequeue(); queue.Dequeue(); Console.WriteLine(queue); //front = 3 rear = 4 count = 1 data = 5 queue.Dequeue(); Console.WriteLine(queue); //queue is empty. queue.Enqueue(0); queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); queue.Enqueue(4); //Queue is full Console.WriteLine(queue); //front = 4 rear = 3 count = 4 data = 0,1,2,3 Console.WriteLine(queue.Peek()); //0 queue.Dequeue(); Console.WriteLine(queue); //front = 0 rear = 3 count = 3 data = 1,2,3 queue.Dequeue(); Console.WriteLine(queue); //front = 1 rear = 3 count = 2 data = 2,3 queue.Dequeue(); Console.WriteLine(queue); //front = 2 rear = 3 count = 1 data = 3 queue.Dequeue(); Console.WriteLine(queue); //queue is empty. queue.Enqueue(9); Console.WriteLine(queue); //front = 3 rear = 4 count = 1 data = 9 Console.ReadLine(); #endregion #region 链式队列 LinkQueue <int> Lqueue = new LinkQueue <int>(); Lqueue.Enqueue(1); Lqueue.Enqueue(2); Lqueue.Enqueue(3); Lqueue.Enqueue(4); Console.WriteLine(Lqueue); Lqueue.Dequeue(); Console.WriteLine(Lqueue); Console.WriteLine(Lqueue.Count()); #endregion #region 双链表 Console.WriteLine("-------------------------------------"); Console.WriteLine("双链表测试开始..."); DbLinkList <string> dblink = new DbLinkList <string>(); dblink.Head = new DbNode <string>("x"); dblink.InsertBefore("w", 0); dblink.InsertBefore("v", 0); dblink.Append("y"); dblink.InsertBefore("z", dblink.Count()); Console.WriteLine(dblink.Count()); //5 Console.WriteLine(dblink.ToString()); //v,w,x,y,z Console.WriteLine(dblink[1]); //w Console.WriteLine(dblink[0]); //v Console.WriteLine(dblink[4]); //z Console.WriteLine(dblink.IndexOf("z")); //4 Console.WriteLine(dblink.RemoveAt(2)); //x Console.WriteLine(dblink.ToString()); //v,w,y,z dblink.InsertBefore("x", 2); Console.WriteLine(dblink.ToString()); //v,w,x,y,z Console.WriteLine(dblink.GetItemAt(2)); //x dblink.Reverse(); Console.WriteLine(dblink.ToString()); //z,y,x,w,v dblink.InsertAfter("1", 0); dblink.InsertAfter("2", 1); dblink.InsertAfter("6", 5); dblink.InsertAfter("8", 7); dblink.InsertAfter("A", 10); //Position is error! Console.WriteLine(dblink.ToString()); //z,1,2,y,x,w,6,v,8 string _tail = dblink.GetItemAt(dblink.Count() - 1); Console.WriteLine(_tail); Console.WriteLine(dblink.TestPrevErgodic()); //8 Console.ReadKey(); //8,v,6,w,x,y,2,1,z #endregion #region 哈夫曼 HuffmanTree huffTree = new HuffmanTree(2, 1, 4, 3); huffTree.Create(); Console.WriteLine("最终树的节点值如下:"); Console.WriteLine(huffTree.ToString()); // 输出结果也许并不直观,对照下面这张图就明白了: // https://pic002.cnblogs.com/images/2010/27612/2010120513101331.png Console.ReadLine(); #endregion #region 顺序堆栈 Console.WriteLine("顺序堆栈测试开始..."); SeqStack <int> seqStack = new SeqStack <int>(10); seqStack.Push(1); seqStack.Push(2); seqStack.Push(3); Console.WriteLine(seqStack); Console.WriteLine(seqStack.Peek()); Console.WriteLine(seqStack); Console.WriteLine(seqStack.Pop()); Console.WriteLine(seqStack); #endregion #region 链堆栈 Console.WriteLine("链堆栈测试开始..."); LinkStack <int> linkStack = new LinkStack <int>(); linkStack.Push(1); linkStack.Push(2); linkStack.Push(3); Console.WriteLine(linkStack); Console.WriteLine(linkStack.Peek()); Console.WriteLine(linkStack); Console.WriteLine(linkStack.Pop()); Console.WriteLine(linkStack); Console.ReadLine(); #endregion #region 23种设计模式 //执行23种设计模式中的一种 StartDesign design = new StartDesign(); design.Go(); #endregion }