C#_泛型

//using System;
//using System.Collections.Generic;
//using System.Text;
//using System.Collections;


//public class LinkedListNode
//{
//    public LinkedListNode(Object value)
//    {
//        this.value = value;
//    }

//    //结点数据值
//    private object value;
//    public object Value
//    {
//        get
//        {
//            return this.value;
//        }
//    }

//    //双向结点指向引用
//    private LinkedListNode next;
//    private LinkedListNode pre;
//    public LinkedListNode Next
//    {
//        get { return this.next; }
//        internal set { this.next = value; }
//    }
//    public LinkedListNode Pre
//    {
//        get { return this.pre; }
//        internal set { this.pre = value; }
//    }
//}

结点的数据存储在Object类型的Value字段中。下面我们来创建链表类,该链表类有一个头结点、尾结点和在链表的末尾添加/删除结点的方法:

双向链表类
//public class LinkedList
//{
//    //头结点
//    private LinkedListNode head;
//    public LinkedListNode Head
//    {
//        get { return this.head; }
//    }
//    //尾结点
//    private LinkedListNode last;
//    public LinkedListNode Last
//    {
//        get { return this.last; }
//    }

//    //在链表尾插入结点
//    public LinkedListNode AddNode(Object value)
//    {
//        LinkedListNode node = new LinkedListNode(value);

//        if (head == null)
//        {
//            head = node;
//            last = head;
//        }
//        else
//        {
//            last.Next = node;
//            node.Pre = last;
//            last = node;
//        }

//        return last;
//    }

//    //在链表尾删除结点
//    public LinkedListNode SubNode()
//    {
//        if (last == null)
//        {
//            return null;
//        }
//        else
//        {
//            LinkedListNode node = last.Pre;
//            node.Next = null;
//            last = node;
//        }

//        return last;
//    }
//}


因为是链表,所以我们希望能使用foreach遍历链表,那么,将链表类LinkedList继承IEnumerable接口并实现GetEnumerator()方法:


//using System;
//using System.Collections.Generic;
using System.;
//using System.Text;
//using System.Collections;

//namespace ConsoleApplication1
//{
//    //结点类
//    public class LinkedListNode
//    {       
//        public LinkedListNode(Object value)
//        {
//            this.value = value;
//        }

//        //结点数据值
//        private object value;
//        public object Value
//        {
//            get
//            {
//                return this.value;
//            }
//        }

//        //双向结点指向引用
//        private LinkedListNode next;
//        private LinkedListNode pre;
//        public LinkedListNode Next
//        {
//            get { return this.next; }
//            internal set { this.next = value;  }
//        }
//        public LinkedListNode Pre
//        {
//            get { return this.pre; }
//            internal set { this.pre = value; }
//        }
//    }

//    //双向链表类
//    public class LinkedList : IEnumerable
//    {
//        //头结点
//        private LinkedListNode head;
//        public LinkedListNode Head
//        {
//            get { return this.head; }
//        }
//        //尾结点
//        private LinkedListNode last;
//        public LinkedListNode Last
//        {
//            get { return this.last; }
//        }

//        //在链表尾插入结点
//        public LinkedListNode AddNode(Object value)
//        {
//            LinkedListNode node = new LinkedListNode(value);

//            if (head == null)
//            {
//                head = node;
//                last = head;
//            }
//            else
//            {
//                last.Next = node;
//                node.Pre = last;
//                last = node;
//            }

//            return last;
//        }

//        //在链表尾删除结点
//        public LinkedListNode SubNode()
//        {
//            if (last == null)
//            {
//                return null;
//            }
//            else
//            {
//                LinkedListNode node = last.Pre;
//                node.Next = null;
//                last = node;
//            }

//            return last;
//        }

//        #region IEnumerable 成员

//        public IEnumerator GetEnumerator()
//        {
//            LinkedListNode curr = head;
//            while (curr != null)
//            {
//                yield return curr.Value;
//                curr = curr.Next;
//            }
//        }

//        #endregion
//    }

//}

//这样我们就可以使用链表了,但该链表中的存储数据只能使Object类型的,这就并不能保证链表中的数据是类型统一的,因此在使用foreach遍历链表时可能出现致命的错误。比如该链表中有整形数据和字符串数据。而且,该链表并不能够为我们提供一个标准的模板。

//下面,我们改进LinkedListNode结点类,使其使用泛型——存储数据的类型使我们任意指定的类型:

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace LinkedListNode
{
   
        public class LinkedListNode<T>
        {
            public LinkedListNode(T value)
            {
                this.value = value;
            }

            //结点数据值
            private T value;
            public T Value
            {
                get
                {
                    return this.value;
                }
            }

            //双向结点指向引用
            private LinkedListNode<T> next;
            private LinkedListNode<T> pre;
            public LinkedListNode<T> Next
            {
                get { return this.next; }
                internal set { this.next = value; }
            }
            public LinkedListNode<T> Pre
            {
                get { return this.pre; }
                internal set { this.pre = value; }
            }
        }

        //同样,也需要将链表类改为泛型类:

        public class LinkedList<T> : IEnumerable<T>
        {
            //头结点
            private LinkedListNode<T> head;
            public LinkedListNode<T> Head
            {
                get { return this.head; }
            }
            //尾结点
            private LinkedListNode<T> last;
            public LinkedListNode<T> Last
            {
                get { return this.last; }
            }

            //在链表尾插入结点
            public LinkedListNode<T> AddNode(T value)
            {
                LinkedListNode<T> node = new LinkedListNode<T>(value);

                if (head == null)
                {
                    head = node;
                    last = head;
                }
                else
                {
                    last.Next = node;
                    node.Pre = last;
                    last = node;
                }

                return last;
            }

            //在链表尾删除结点
            public LinkedListNode<T> SubNode()
            {
                if (last == null)
                {
                    return null;
                }
                else
                {
                    LinkedListNode<T> node = last.Pre;
                    node.Next = null;
                    last = node;
                }

                return last;
            }

            #region IEnumerable 成员

            public IEnumerator<T> GetEnumerator()
            {
                LinkedListNode<T> curr = head;
                while (curr != null)
                {
                    yield return curr.Value;
                    curr = curr.Next;
                }
            }

            IEnumerator IEnumerable.GetEnumerator()
            {
                return GetEnumerator();
            }
            #endregion
        }
    class Program
    {
        static void Main(string[] args)
        {
            LinkedList<int> list2 = new LinkedList<int>();
            list2.AddNode(1);
            list2.AddNode(3);
            list2.AddNode(5);
          
            Console.WriteLine("Before Sub:");
            foreach (int i in list2)
            {
                Console.WriteLine(i);
            }
           
            Console.WriteLine("After Sub:");
            list2.SubNode();
            foreach (int i in list2)
            {
              
                Console.WriteLine(i);
            }
            Console.ReadLine();
        }
    }
}


//这样我们就保证了链表中数据的统一性,因此可以安全的使用foreach遍历链表了。

//其实,我个人认为,泛型也就是我们在编写代码时并不知道要使用的数据类型是什么,而是在使用代码时规定数据类型的,这样,我们就很容易的创建复用的模板代码,即减少了代码编写的工作,也节省了空间资源。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值