泛型节点声明
Microsoft 将此作为学习泛型的冒泡排序示例。直到第 76 行和第 77 行才有意义。这些声明怎么可能呢?节点是一个类。不需要用new实例化吗? 您将如何优化排序?哪一部分是通用的,哪一部分是非通用的?
1 public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
2 {
3 protected Node head;
4 protected Node current = null;
5
6 // Nested class is also generic on T
7 protected class Node
8 {
9 public Node next;
10 private T data; //T as private member datatype
11
12 public Node(T t) //T used in non-generic constructor
13 {
14 next = null;
15 data = t;
16 }
17
18 public Node Next
19 {
20 get { return next; }
21 set { next = value; }
22 }
23
24 public T Data //T as return type of property
25 {
26 get { return data; }
27 set { data = value; }
28 }
29 }
30
31 public GenericList() //constructor
32 {
33 head = null;
34 }
35
36 public void AddHead(T t) //T as method parameter type
37 {
38 Node n = new Node(t);
39 n.Next = head;
40 head = n;
41 }
42
43 // Implementation of the iterator
44 public System.Collections.Generic.IEnumerator<T> GetEnumerator()
45 {
46 Node current = head;
47 while (current != null)
48 {
49 yield return current.Data;
50 current = current.Next;
51
52 }
53 }
54
55 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
56 {
57 return GetEnumerator();
58 }
59 }
60
61 public class SortedList<T> : GenericList<T> where T : System.IComparable<T>
62 {
63 // A simple, unoptimized sort algorithm that
64 // orders list elements from lowest to highest:
65
66 public void BubbleSort()
67 {
68 if (null == head || null == head.Next)
69 {
70 return;
71 }
72 bool swapped;
73
74 do
75 {
76 Node previous = null;
77 Node current = head;
78
79
80 //Console.WriteLine(previous.GetType());
81 //Console.ReadLine();
82
83 swapped = false;
84
85
86 //Debug.WriteLine(p);
87 //Debug.WriteLine("Testing " + current.ToString());
88
89 while (current.next != null)
90 {
91 // Because we need to call this method, the SortedList
92 // class is constrained on IEnumerable<T>
93 if (current.Data.CompareTo(current.next.Data) > 0)
94 {
95 Node tmp = current.next;
96 current.next = current.next.next;
97 tmp.next = current;
98
99 if (previous == null)
100 {
101 head = tmp;
102 }
103 else
104 {
105 previous.next = tmp;
106 }
107 previous = tmp;
108 swapped = true;
109 }
110 else
111 {
112 previous = current;
113 current = current.next;
114 }
115 }
116 } while (swapped);
117 }
118 }
Microsoft gives this as an Bubble sort example for learning generics. It makes sense until I get to lines 76 and 77. How are those declarations possible? Node is a class. Don't you have to instantiate it with new?
How would you optimize the sort? Which is part is generic and which is non-generic?
1 public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
2 {
3 protected Node head;
4 protected Node current = null;
5
6 // Nested class is also generic on T
7 protected class Node
8 {
9 public Node next;
10 private T data; //T as private member datatype
11
12 public Node(T t) //T used in non-generic constructor
13 {
14 next = null;
15 data = t;
16 }
17
18 public Node Next
19 {
20 get { return next; }
21 set { next = value; }
22 }
23
24 public T Data //T as return type of property
25 {
26 get { return data; }
27 set { data = value; }
28 }
29 }
30
31 public GenericList() //constructor
32 {
33 head = null;
34 }
35
36 public void AddHead(T t) //T as method parameter type
37 {
38 Node n = new Node(t);
39 n.Next = head;
40 head = n;
41 }
42
43 // Implementation of the iterator
44 public System.Collections.Generic.IEnumerator<T> GetEnumerator()
45 {
46 Node current = head;
47 while (current != null)
48 {
49 yield return current.Data;
50 current = current.Next;
51
52 }
53 }
54
55 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
56 {
57 return GetEnumerator();
58 }
59 }
60
61 public class SortedList<T> : GenericList<T> where T : System.IComparable<T>
62 {
63 // A simple, unoptimized sort algorithm that
64 // orders list elements from lowest to highest:
65
66 public void BubbleSort()
67 {
68 if (null == head || null == head.Next)
69 {
70 return;
71 }
72 bool swapped;
73
74 do
75 {
76 Node previous = null;
77 Node current = head;
78
79
80 //Console.WriteLine(previous.GetType());
81 //Console.ReadLine();
82
83 swapped = false;
84
85
86 //Debug.WriteLine(p);
87 //Debug.WriteLine("Testing " + current.ToString());
88
89 while (current.next != null)
90 {
91 // Because we need to call this method, the SortedList
92 // class is constrained on IEnumerable<T>
93 if (current.Data.CompareTo(current.next.Data) > 0)
94 {
95 Node tmp = current.next;
96 current.next = current.next.next;
97 tmp.next = current;
98
99 if (previous == null)
100 {
101 head = tmp;
102 }
103 else
104 {
105 previous.next = tmp;
106 }
107 previous = tmp;
108 swapped = true;
109 }
110 else
111 {
112 previous = current;
113 current = current.next;
114 }
115 }
116 } while (swapped);
117 }
118 }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
C# 中的
class
类型可以使用null
或与声明类型兼容的值进行初始化。第 76 行和第 77 行看起来像这样这里值
null
是合法的。它本质上是在说“我没有价值”。对head
的赋值也是合法的,因为head
也是Node
类型。结果是两个引用head
和current
引用相同的Node
对象值。通过其中一个引用修改Node
实例将对另一个引用可见。A
class
type in C# can be initialized withnull
or a value which is of a compatible type with the declaration. Lines 76 and 77 look like soHere the value
null
is legal. It essentially says "I have no value". The assignment tohead
is also legal becausehead
is also of typeNode
. The result is the two referenceshead
andcurrent
refer to the sameNode
object value. Modifying theNode
instance through one of the references will be visible to the other.您将
previous
和next
分别分配给null
和head
。这是一个赋值操作,就像其他操作一样。除非您实际创建对象的新实例,否则不需要使用 new。通用部分是引用
T
的任何内容。它是实例化类时提供的泛型类型。一个很好的例子是List
,它创建T
类型的对象列表。您可以将其实例化为List
(表示字符串列表)、List
(表示整数列表)等。You're assigning
previous
andnext
tonull
andhead
respectively. It's an assignment operation, just like any other. You don't need to use new unless you're actually creating a new instance of the object.The generic parts are anything that refers to
T
. It's a generic type that is supplied when the class is instanciated. A good example isList<T>
, which creates a list of objects of typeT
. You could instance this asList<string>
for a list of strings,List<int>
for a list of ints, etc.这些引用可能指向类的实例,也可能只是
null
。您可以将引用分配给其他引用:
These are references that could be pointing to instances of a class or can be just
null
.You can assign references to other references:
该代码中的第 76 行和第 77 行没有实例化任何对象。正如您所说,
Node
是一个类。 .NET 中的类始终是引用类型,这意味着:null
,这意味着该变量不引用任何内容。No objects are being instantiated on lines 76 and 77 in that code. As you said,
Node
is a class. Classes in .NET are always reference types which means that:null
, which means that the variable references nothing.