C# 双向链表及自定义链表

一、双向链表LinkedList 

      LinkedList集合类没有非泛型集合的类似版本。LinkedList是一个双向链表,其元素指向它前面和后面的元素。
链表的优点是,如果将元素插入列表的中间位置,使用链表会非常快。在插入一个元素时,只需修改上一个元素的Next引用和下一个元素的Previous引用,使它们引用所插入的元素。在List和ArrayList类中,插入一个元素,需要移动该元素后面的所有元素。
当然,链表也有缺点。链表的元素只能一个接一个地访问,这需要较长的时间来查找位于链表中间或尾部的元素。
链表不仅能在列表中存储元素,还可以给每个元素存储下一个元素和上一个元素的信息。这就是
LinkedList包含LinkedListNode类型的元素的原因。使用LinkedListNode 类,可以获得列表中的下一个元素和上一个元素. 
#region 链表测试 /**/ ///

/// 链表测试 /// public class TestLinkedList { public void TestLinkList() { LinkedList bookList = new LinkedList(); Book book1 = new Book { Title = "C#高级编程", Book_Author = new Author { Name = "黄老邪", Address = "桃花岛" }, Price = 128f }; Book book2 = new Book { Title = "Think in Java", Book_Author = new Author { Name = "欧阳峰", Address = "白驼山" }, Price = 138f }; Book book3 = new Book { Title = "silverlight", Book_Author = new Author { Name = "一灯大师", Address = "大理" }, Price = 123f }; Book book4 = new Book { Title = "JavaFx", Book_Author = new Author { Name = "洪七公", Address = "临安" }, Price = 125f }; Book book5 = new Book { Title = "WPF", Book_Author = new Author { Name = "王重阳", Address = "临安" }, Price = 158f }; /**/ ///将book1添加到链表第一个元素 bookList.AddFirst(book1); /**/ ///将book2添加到链表第一个元素,这时原来的第一个元素会自动退后一位 bookList.AddFirst(book2); /**/ ///实例化一个LinkedListNode 对象 LinkedListNode node = new LinkedListNode(book3); /**/ ///将LinkedListNode 对象添加到链表最后 bookList.AddLast(node); /**/ ///在最后一个元素后追加一个元素 bookList.AddAfter(node, book4); /**/ ///在LinkedListNode 对象前插入一个元素 bookList.AddBefore(node, book5); foreach (var item in bookList) { Console.WriteLine(item.Title); } /**/ ///顺序显示 /// Console.WriteLine("/n/n顺序显示链表内的元素"); LinkedListNode firstNode = bookList.First; while (firstNode != null) { Console.WriteLine(firstNode.Value.Title); firstNode = firstNode.Next; } /**/ ///逆序显示 Console.WriteLine("/n/n逆序显示链表内的元素"); LinkedListNode lastNode = bookList.Last; while (lastNode != null) { Console.WriteLine(lastNode.Value.Title); lastNode = lastNode.Previous; } Console.WriteLine("/n/n排序后的结果"); var orderList = bookList.OrderBy(book => book.Price); foreach (var item in orderList) { Console.WriteLine(string.Format("图书名称{0},价格{1}", item.Title, item.Price)); } } } #endregion

 

二、自定义链表

public class Node { public T data; public Node() { } public Node(T data) { this.data = data; } public Node next = null; } public class Link { //定义链表的头节点 private Node head; //链表初始化 public Link() { head = null; } ///

/// 链表的长度,遍历整个链表,直到链表结尾 /// /// 链表的长度 public int Count() { //定义一个节点 Node p = head; int count = 0;//链表计数器 //遍历链表 while (p != null) { count++; p = p.next;//移到下一个节点 } return count; } /// /// 取链表的第i个节点的值 /// /// 第i个节点 /// 第i个节点的值 public T GetElem(int i) { //定义一个节点 Node p = head; int k = 0;//计数器 //如果i大于链表的长度或i小于0,则报出异常 if (i >= Count() || i < 0) { throw new Exception("Error"); } //如果i大于0且小于链表长度,则遍历链表直到第i个节点为止 while (k < i) { k++; p = p.next; } return p.data; } /// /// 在链表的第i个位置上插入新的节点 /// /// 要插入节点的值 /// 链表的第i个节点 public void Insert(T e, int i) { Node p = new Node(e);//要插入的节点 Node q = head; int k = 0;//计数器 //如果i大于链表的长度或i小于0,则报出异常 if (i >= Count() || i < 0) { System.Console.WriteLine("Error"); return; } //如果在链表头插入,移动头指针 if (i == 0) { p.next = head; head = p; return; } //遍历链表直到第i-1个节点为止 while (k < i - 1) { k++; q = q.next; } //把新节点插入在第i个节点的位置 p.next = q.next; q.next = p; } /// /// 删除第i个节点 /// /// 链表的第i个节点 public void RemoveAt(int i) { Node p = head; int k = 0;//计数器 //如果i大于链表的长度或i小于0,则报出异常 if (i < 0 || i >= Count()) { System.Console.WriteLine("Error"); return; } //如果删除链表头,移动头指针 if (i == 0) { head.next = head.next.next; return; } //遍历链表直到第i-1个节点为止 while (k < i - 1) { k++; p = p.next; } //删除第i个节点 p.next = p.next.next; } /// /// 在链表尾加入一个新的节点 /// /// 新的节点的值 public void Add(T e) { Node p = new Node(e);//创建一个新的节点 Node q = new Node(); //如果链表为空,则将新节点赋给头指针 if (head == null) { head = p; return; } /*--------------------------------------- * 如果链表不为空,则在链表尾加入新的节点 ----------------------------------------*/ //从头指针开始遍历,直至链表尾 q = head; while (q.next != null) { q = q.next; } //在链表尾插入新节点 q.next = p; } /// /// 查找某个元素在链表中第一次出现的位置 /// /// 要查找的元素 /// 这个元素在链表中第一次出现的位置的索引 public int IndexOf(T e) { Node p = head; int k = 0;//计数器 /*------------------------------------ * 遍历整个链表,直到找到第一个节点的值 * 与该元素相等退出,并返回相应的位置索 * 引。如果没有找到,则返回-1。 -------------------------------------*/ //从头指针开始遍历,找到退出,并返回相应的位置索引 while (p.next != null) { if (p.data.Equals(e)) { return k; } k++; p = p.next; } if (!p.data.Equals(e)) { k++; } //如果没有找到,则返回-1 return k >= Count() ? -1 : k; } /// /// 查找某个元素在链表中最后一次出现的位置 /// /// 要查找的元素 /// 这个元素在链表中最后一次出现的位置的索引 public int LastIndexOf(T e) { Node p = head; int index = -1;//最后一次出现的位置索引 int k = 0;//计数器 /*------------------------------------------------ * 遍历整个链表,直到链表结束,每发现相应节点的值 * 与该元素相等,则将该节点的位置索引赋给index, * 这样index的值就是最后一次的值。如果没有,则返 * 回-1 -------------------------------------------------*/ while (p.next != null) { if (p.data.Equals(e)) { index = k; } k++; p = p.next; } if (p.data.Equals(e)) { index = k; } return index; } /// /// 判断链表是否为空 /// /// public bool Empty() { return head == null ? true : false; } /// /// 清空链表 /// public void Clear() { head = null; } /// /// 将链表转成数组 /// /// 转换后的数组 public T[] ToArray() { T[] array = new T[Count()];//定义一个与链表长度相同的数组 /*------------------------------------------------ * 遍历链表,将链表的每个节点的值放到相应的数组里 ------------------------------------------------*/ Node p = head; int i = 0;//数组下标计数器 while (p.next != null) { array[i++] = p.data; p = p.next; } array[Count() - 1] = p.data; return array; } /// /// 将一个数组加到链表中 /// /// 要加入链表的数组 public void AddRange(T[] a) { //遍历整个数组,将数组中的每个元素作为一个新的节点加入到链表中 for (int i = 0; i < a.Length; i++) { Add(a[i]); } } /// /// 删除链表中值为某个元素的所有节点 /// /// 要删除节点的值 public void Remove(T e) { //如果头指针的值等于这个元素,则删这个结点,并将头指针后移 while (head.data.Equals(e)) { head = head.next; } //如果不是头指针,则删除该节点 Node p = head; while (p.next.next != null) { if (p.next.data.Equals(e)) { p.next = p.next.next; continue; } p = p.next; } if (p.next.data.Equals(e)) { p.next = null; } } /// /// 将链表中所有为某个值的节点替换为另一个值 /// /// 被替换的值 /// 替换的值 public void Replace(T first, T second) { Node p = head; while (p.next != null) { if (p.data.Equals(first)) { p.data = second; } p = p.next; } if (p.data.Equals(first)) { p.data = second; } } /// /// 链表反转 /// public void Reverse() { Node p = head; Node newhead = head; Node q = p; p = p.next; newhead.next = null; while (p.next != null) { q = p; p = p.next; q.next = newhead; newhead = q; } q = p; q.next = newhead; newhead = p; head = newhead; } } 

你可能感兴趣的:(C#,c#,null,silverlight,javafx,exception,class)