1. 程式人生 > >C#學習筆記(十八):數據結構和泛型

C#學習筆記(十八):數據結構和泛型

eric 訪問 空間 cap 添加數據 mes 出錯 雙向 添加

數據結構

技術分享圖片

技術分享圖片

技術分享圖片

只有這四種 a、集合:數據之間沒有特定的關系 b、線性結構:數據之間有一對一的前後聯系 c、樹形結構:數據之間有一對多的關系,一個父節點有多個子節點,一個子節點只能有一個父節點 d、圖狀結構:數據之間有多對多的關系,一個節點可以有多個子節點,也可以多個父節點 技術分享圖片 線性結構:列表、鏈表、棧、隊列 樹形結構:字典 技術分享圖片

技術分享圖片

列表(數據量小,100以下,無腦使用) 1、列表可以動態增長,數組不可以動態增長 2、列表可以不通過下標添加元素,數組不可以 3、列表索引元素特別快(首地址加下標),但是內存中的元素必須相連,不允許跳過單元格 4、列表修改元素效能差,當刪除(插入)元素時,需要把後面的元素一個個的向前(向後)移 技術分享圖片
鏈表(數據量大,萬計以上) 若幹個小塊構成,每個小塊由三個單元格構成,若幹個單元格相互關聯(當前元素的後一元素指向下一個元素的當前元素) 雙向鏈表:前一元素、當前元素、後一元素 單向鏈表:當前元素、後一元素 1、動態增長 2、C#鏈表沒有下標 3、索引元素特別慢,一個個查找,可以用叠代器優化 4、元素不是相連的,修改元素特別快 技術分享圖片

技術分享圖片

技術分享圖片

技術分享圖片

散列結構:數據取余,哈希表,哈希算法MD5(把無限的數據存儲在有限的空間中) 碰撞:兩個數據取余相同,盡量避免數據相同(索引:必須唯一,值:可以相同) 技術分享圖片

技術分享圖片

1、允許任意類型(不考慮具體類型,只考慮變化關系) 2、但必須是同一類型 技術分享圖片

技術分享圖片

泛型:統一代碼邏輯應用於所有類型

技術分享圖片

泛型集合和集合功能相似,增加了泛型的特性 集合:需要轉成Object,存在性能消耗,轉換會出錯 泛型集合:通過翻譯官轉化,效能無損 技術分享圖片

技術分享圖片

List列表 Capcity默認長度、Count實際元素個數、Data(Int[])數組 添加元素超過默認長度,會調用Data重新創建一個Capcity * 2的新數組,舊數組變為垃圾 添加準確的初始長度,或給出一個合理基數,可以減少性能消耗 技術分享圖片

技術分享圖片

技術分享圖片

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace m1w4d4_list { //在我們要使用泛型集合時 //首先我們要確認是否using System.Collections.Generic; class Monster { } class Program { //我們學習了列表的數據結構(增刪改查) //實例化,屬性 //增加元素 //刪除元素 //訪問,修改元素 //插入元素 //查找元素 static void Main(string[] args) { #region 泛型列表 //泛型列表允許我們做任意類型的列表,只需要在<>中填入相應類型 List<int> list = new List<int>();//這種構造讓我使用默認的初始長度(4) List<int> list1 = new List<int>(10);//這種構造允許我們設置列表的初始長度 List<Monster> list3 = new List<Monster>(); //list.Capacity; Capacity表示列表的實際長度 //list.Count; Count表示list中有多少個有意義的元素 //添加元素 list.Add(123); //訪問元素 //通過索引器可以訪問對應元素,但索引器的標號必須小於Count Console.WriteLine(list[0]); Console.WriteLine(list.Capacity);//初始為0.由Add創建 Console.WriteLine(); //修改元素 for (int i = 0; i < 10; i++) { list.Add(i); } for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\t"); list[4] = 999; for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\n"); //刪除元素 list.RemoveAt(0);//移除指定下標中的元素 for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine(); list.Remove(999);//移除指定元素(從頭查找到的) for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\n"); //插入元素 //list.Insert();//在指定下標處,插入指定元素,原元素及其後的元素均排在插入元素的後方 list.Insert(4, 999); for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\n"); //查找元素 //從頭查找 int id = list.IndexOf(999);//根據元素從頭查找,並返回找到的第一個元素的位置 Console.WriteLine($"從頭查找,刪除值為{list[id]}的元素"); list.RemoveAt(id);//刪除從頭找到的第一個元素 for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\n"); //從尾查找 int id1 = list.LastIndexOf(8);//根據元素從尾查找,並返回找到的第一個元素的位置 Console.WriteLine($"從頭查找,刪除值為{list[id1]}的元素"); list.RemoveAt(id);//刪除從尾找到的第一個元素 for (int i = 0; i < list.Count; i++) { Console.Write(list[i] + " "); } Console.WriteLine("\n"); #endregion //遍歷 //用for,遍歷次數是Count //for (int i = 0; i < list.Count; i++) //{ // Console.Write(list[i] + " "); //} //用foreach //foreach (var item in list) //{ //} #region 練習1 //建立一個整型List,給List中添加倒序添加10-1 Console.WriteLine("建立一個整型List,給List中添加倒序添加10-1"); for (int i = 10; i >= 1; i--) { list1.Add(i); } //刪除List中的第五個元素 list1.RemoveAt(4); //遍歷剩余元素並打印出來 foreach (var item in list1) { Console.Write(item + " "); } Console.WriteLine(); #endregion } } }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace m1w4d4_list1
{
    #region 泛型列表排序IComparable
    public class Monster : IComparable<Monster>
    {
        public Monster(string name, int attack, int defend, int health)
        {
            this.name = name;
            this.attack = attack;
            this.defend = defend;
            this.health = health;
        }
        public string name;
        public int attack;
        public int defend;
        public int health;
        public override string ToString()
        {
            return string.Format("{0},攻擊{1},防禦{2},血量{3}", name, attack, defend, health);
        }
        public static int DefendSort(Monster a, Monster b)
        {
            return a.defend - b.defend;
        }
        public int CompareTo(Monster other)
        {
            //比較某一個參數,返回對應值
            //如果大就返回大於0的數,自己排在對比參數的後面
            //如果小就返回小於0的數,自己排在對比參數的前面
            //如果相等就返回0,不換
            //這樣在外部調用Sort的時候會形成一個以這個參數為標準的升序排序
            return attack - other.attack;
        }
    }
    #endregion
    #region 泛型列表排序IComparer
    class MonsterAttackSort : IComparer<Monster>
    {
        //這個方法是用 參數x 和參數y 比較,返回相應整數
        //如果返回大於零的數,x將放在y的後面,如果用升序的邏輯,就是x比y大
        //如果返回大於零的數,x將放在y的後面
        //如果返回零,表示相等
        public int Compare(Monster x, Monster y)
        {
            return x.attack - y.attack;
        }
    }
    class MonsterDefendSort : IComparer<Monster>
    {
        public int Compare(Monster x, Monster y)
        {
            return x.defend - y.defend;
        }
    }
    class MonsterHealthSort : IComparer<Monster>
    {
        public int Compare(Monster x, Monster y)
        {
            return x.health - y.health;
        }
    }
    #endregion
    class Program
    {
        #region 泛型列表排序Comparition
        static int AttackSort(Monster a, Monster b)
        {
            return a.attack - b.attack;
        }
        #endregion
        //用一個List排序
        //泛型集合都是實現System.Collections.Generic;中對應接口的一些類型
        //如果要實現一個自定義類的排序
        //1、實現一個IComparable的接口
        //2、調用Sort的重載,用一個接口類型IComparer
        //3、調用Sort的重載,用一個委托類型Comparition
        //需要一個和List裝載的類型相同的一排序方法 int 函數名 (對應類型 對應類型)
        static void Main(string[] args)
        {
            #region 泛型列表排序
            Random roll = new Random();
            List<int> list = new List<int>();
            for (int i = 10 - 1; i >= 0; i--)
            {
                list.Add(roll.Next(0, 100));
            }
            foreach (var item in list)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine("\n");
            list.Sort();//通過Sort對List進行(升序)排序
            foreach (var item in list)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine("\n");
            list.Reverse();//通過Sort對List進行(升序)排序
            foreach (var item in list)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine("\n");
            #endregion
            #region 排100000個數
            //用冒泡排序,排100000個數,速度沒有Sort快
            List<int> list1 = new List<int>();
            for (int i = 0; i < 100000; i++)
            {
                list1.Add(roll.Next(0, 100));
            }
            int temp = list1[0];
            for (int i = 0; i < 100000 - 1; i++)
            {
                for (int j = 0; j < 100000 - 1 - i; j++)
                {
                    if (list1[i] > list1[i + 1])
                    {
                        temp = list1[i];
                        list1[i] = list1[i + 1];
                        list1[i + 1] = temp;
                    }
                }
            }
            foreach (var item in list1)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine("\n");
            //用Sort排序,排100000個數
            List<int> list2 = new List<int>();
            for (int i = 0; i < 100000 - 1; i++)
            {
                list2.Add(roll.Next(0, 100));
            }
            list2.Sort();
            foreach (var item in list2)
            {
                Console.Write(item + "  ");
            }
            Console.WriteLine("\n");
            #endregion
            #region 泛型列表排序IComparable
            List<Monster> monsterList = new List<Monster>();
            for (int i = 0; i < 10; i++)
            {
                monsterList.Add(new Monster("怪物" + (i + 1) + "", roll.Next(10, 20), roll.Next(10, 20), roll.Next(10, 20)));
            }
            monsterList.Sort();
            foreach (var item in monsterList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("\n");
            #endregion
            #region 泛型列表排序IComparer
            //排序器
            MonsterAttackSort mAttackSort = new MonsterAttackSort();
            MonsterDefendSort mDefendSort = new MonsterDefendSort();
            MonsterHealthSort mHealthSort = new MonsterHealthSort();
            monsterList.Sort(mAttackSort);
            monsterList.Sort(mDefendSort);
            monsterList.Sort(mHealthSort);
            //monsterList.Reverse();
            foreach (var item in monsterList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("\n");
            #endregion
            #region 泛型列表排序Comparition
            monsterList.Sort(AttackSort);
            foreach (var item in monsterList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("\n");
            monsterList.Sort((a,b)=>-(a.health - b.health));
            foreach (var item in monsterList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("\n");
            monsterList.Sort(Monster.DefendSort);
            foreach (var item in monsterList)
            {
                Console.WriteLine(item);
            }
            Console.WriteLine("\n");
            #endregion
        }
    }
}

復習

委托補充

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 委托補充
{
    // 創建一個數據類型
    delegate void Del1();
    delegate void Del2(int n);
    delegate void Del3(string n);
    delegate void Del4(int a, string b, char c, bool d);
    delegate int Del5();
    delegate string Del6(int n);
    delegate int Del7(int a, string b, bool c);
    class Program
    {
        static void Main(string[] args)
        {
            #region 沒有返回值的委托 Action
            // Aciton 針對於沒有返回值的委托
            // 沒有參數的 那就不用泛型的 直接用Aciton
            // 有參數的 那就根據參數的個數和類型來使用泛型的Aciton<T1 a, T2 b, T3 c ....>
            // 使用
            Del1 del1 = delegate () { Console.WriteLine("這是一個沒有參數,沒有返回值的委托"); };
            Action del1 = delegate () { Console.WriteLine("這是一個沒有參數,沒有返回值的委托"); };
            del1();
            //Del2 del2 = n => Console.WriteLine("這是一個沒有返回值,有一個參數的委托");
            Action<int> del2 = n => Console.WriteLine("這是一個沒有返回值,有一個參數的委托" + n);
            del2(100);
            Action<string> del3 = n => Console.WriteLine("這是一個沒有返回值,有一個字符串的參數的委托" + n);
            del3("abc");
            Action<int, string, char, bool> del4 = (int a, string b, char c, bool d) => { };
            #endregion
            #region 有返回值的委托  Func<T1, T2, T3....>  最後一個占位符 永遠對應返回值類型  (占位符最少有1個,最多可以有20多個,來表示返回值類型的)
            Func<int> del5 = () => 0;
            Func<int, string> del6 = abc => abc.ToString();
            Func<int, string, bool, int> del7 = (a, b, c) => a;
            #endregion
            #region Predicate有一個參數,參數的類型由泛型占位符指定 返回值 bool
            Predicate<string> del9 = a => true;
            #endregion
            #region Comparison<int> 有兩個參數都是根據泛型占位符指定的類型 返回值int
            Comparison<string> del8 = (a, b) => a.Length - b.Length;
            #endregion
        }
    }
}

泛型列表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 泛型列表
{
    class Program
    {
        static void Main(string[] args)
        {
            // List 動態數組
            List<int> array = new List<int>();
            List<int> array2 = new List<int>() { 303, 27, 309, 40 };     // 使用初始化器添加數據
            //
            array.Add(1000);
            array.AddRange(new int[] { 1, 2, 3, 42 });//AddRange批量增加,數組和列表
            array.AddRange(array2);
            ////array.Remove(1000);   // 刪到找到的第一個 沒找到也不發生什麽
            //array.RemoveAt(0);
            //array.RemoveRange(0, 3);  // 刪除一定範圍的元素  從哪個下標開始, 總共刪除幾個元素
            //array.RemoveAll(n => n % 2 == 0);   // 把所有偶數全部刪除
            ////array[0] = 888;
            //
            int index = array.IndexOf(301);       // 找不到會返回 -1
            Console.WriteLine("找到的下標為:" + index);
            index = array.LastIndexOf(301);
            Console.WriteLine("找到的下標為:" + index);
            int result = array.Find(n => n % 40 == 0);   // 找到匹配條件的第一個元素,Find查找返回的是元素
            Console.WriteLine(result);
            List<int> resultArray = array.FindAll(n => n % 3 == 0);//FindAll查找返回的是新的列表
            foreach (var item in resultArray)
            {
                Console.Write(item + "\t");
            }
            // 遍歷
            //for (int i = 0; i < array.Count; i++)
            //{
            //    Console.Write(array[i] + "\t");
            //}
            Console.WriteLine();
        }
    }
}

C#學習筆記(十八):數據結構和泛型