第18天C#哈希、栈、队列、单链表

哈希表(Hashtable )

类代表了一系列基于键的哈希代码组织起来的键/值对。它使用键来访问集合中的元素。当您使用键访问元素时,则使用哈希表,而且您可以识别一个有用的键值。哈希表中的每一项都有一个键/值对。键用于访问集合中的项目。

API

Hashtable hash = new Hashtable();
hash.Add(1, "first");                       //添加键值对
hash.Add(false, 123);
hash.Add("str", true);
int count = hash.Count;                     //获取哈希表中包含元素的个数
bool isHaveKey = hash.ContainsKey(1);       //判断哈希表是否包含指定的键
bool isHaveKey2 = hash.Contains(2);         //同样判断键
bool isHaveValue = hash.ContainsValue(123); //判断是否含有指定的值
ICollection keys = hash.Keys;               //获取哈希表所有的键
foreach (var item in keys)
{
    Console.WriteLine(item); //遍历键名
}
Console.WriteLine("--------------");
ICollection values = hash.Values;           //获取哈希表所有的值
foreach (var item in values)
{
    Console.WriteLine(item);
}
hash.Remove(1);                             //按照指定索引删除相对应的元素
Console.WriteLine("---------------");
foreach (DictionaryEntry item in hash)      //遍历哈希表键值对
{
    Console.WriteLine(item.Key);
    Console.WriteLine(item.Value);
}
bool isSize = hash.IsFixedSize;             //获取一个值表示是否有固定大小
bool isRead = hash.IsReadOnly;              //判断哈希表是否只读
Console.WriteLine("************");
Console.WriteLine(isRead);
hash.Clear();                               //清空哈希表

哈希表和字典的区别

概念

堆栈(Stack)代表了一个先进后出的对象集合,当需要对各项进行先进后出的访问时,则使用堆栈

泛型栈

队列

概念

队列(Queue)代表了一个先进先出的对象集合,当需要对各项进行先进先出的访问时,则使用队列

 

链表

 优缺点

链表分类

单向链表

当前每一个节点只存储指向下一个节点的地址

双向链表

每一个节点中存储前一个节点的地址和后一个节点的地址

环形链表

头尾连接

链表分为两部分

节点类

数据

指向(指针域):下一个节点/前一个节点

    class Node<T>
    {
        private T data;             //数据
        private Node<T> next;       //指针

        public Node(Node<T> next)
        {
            this.next = next;                       //首节点 只有指针没有值
        }
        public Node(T data)
        {
            this.data = data;                       //尾结点 只有值没有指针
        }
        public Node(T data, Node<T> next)           //中间各节点
        {
            this.Data = data;
            this.Next = next;
        }
        public Node()                               //无参构造
        {
            this.data = default(T);
            this.next = null;
        }

        public T Data
        {
            get
            {
                return data;
            }

            set
            {
                data = value;
            }
        }

        internal Node<T> Next
        {
            get
            {
                return next;
            }

            set
            {
                next = value;
            }
        }
    }

链表类

头节点

    class LinkList<T>
    {
        private Node<T> first;

        internal Node<T> First
        {
            get
            {
                return first;
            }

            set
            {
                first = value;
            }
        }

        public LinkList()
        {
            this.First = null;
        }


        public void Add(T data)
        {
            Node<T> node = new Node<T>(data);//先创建一个节点,数据传进去
            Node<T> tmp = new Node<T>() ;    //如果首节点不为空 定义临时节点
            if (first == null)
            {
                first = node;               //如果首节点是空,则把值赋给首节点
                return;
            }
            tmp = first;
            while (tmp.Next!=null)           
            {
                tmp = tmp.Next;             //让临时节点不断的指向下个节点,直到下个节点为空,那么这个节点则是最后一个节点
            }
            tmp.Next = node;                     //把带有数据的节点赋值给最后一个节点的next


        }
        public int GetLength()                      //链表长度
        {
            int index = 0;
            Node<T> tmp = first;
            while(tmp != null)
            {
                index++;
                tmp = tmp.Next;
            }
            return index;
        }

        public void DisPlay()                       //显示链表数据
        {
            Node<T> tmp = first;            
            while(tmp!=null)
            {
                Console.Write(tmp.Data + " ");
                tmp = tmp.Next;
            }
        }
        public bool IsEmpty()                         //判断链表是否为空
        {
            if(first==null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public void Insert(int index, T data)
        {
            Node<T> node = new Node<T>(data);
            if (index < 0 || index>GetLength()||IsEmpty())
            {
                throw new Exception("数组越界");
            }
            else if(index==0)                           //索引为0时,把数据的next指向首节点,
            {
                node.Next = first;
                first = node;
            }
            else if(index==GetLength())                 //索引跟链表长度一致时,就是添加数据
            {
                Add(data);
            }
            else
            {
                int count = 0;
                Node<T> p = first;
                Node<T> tmp = new Node<T>();
                while(count!=index)
                {
                    count++;
                    tmp = p;                //把首节点给tmp
                    p = p.Next;             //把p的下一个节点给p  此时关系是   tmp p  tmp在p前面

                }
                if (index == count)         //如果到了索引的位置,则开始把数据放到tmp和p的中间
                {
                    tmp.Next = node;
                    node.Next = p;
                }
            }
        }

        //查找链表第i个数据
        public T GetValue(int index)
        {
            int count = 0;
            if(index<0||IsEmpty()||index>GetLength())
            {
                throw new Exception("数组越界");
            }else
            {
                Node<T> tmp = first;
                while(count!=index)                     //循环直到给定的索引值
                {
                    count++;
                    tmp = tmp.Next;                         
                }
                return tmp.Data;                        //把数值return出去
            }
        }

        //删除第i个元素
        public T Delete(int index)
        {
            int count = 0;
            if (index < 0 || IsEmpty() || index > GetLength())
            {
                throw new Exception("数组越界");
            }
            else
            {
                
                if(index==0)
                {
                    T data = first.Data;                    //首节点的值抛出
                    first = first.Next;                     //首节点指向下一个指针指向首节点
                    return data;
                }
                else
                {
                    Node<T> p = first;
                    Node<T> tmp = new Node<T>();
                    while (count != index)                     //循环直到给定的索引值
                    {
                        count++;
                        tmp = p;                                //p节点赋值给临时节点  此时顺序为tmp p
                        p = p.Next;
                        
                    }
                    if(count == index)
                    {
                        tmp.Next = p.Next;                      //把tmp的指针直接指向p的下一个指针,断开了tmp原本的下一个指针
                        return p.Data;
                    }

                }
               
                return default(T);
            }
        }
    }
原文地址:https://www.cnblogs.com/yifengs/p/14110032.html