【C#数据结构与算法 Marcin Jamro】第二章 Arrays and Lists

数组:单维数组、多维数组、锯齿数组

排序算法: 选择排序、插入排序、冒泡排序、、快速排序

简单lists: 数组列表、通用列表、示例-平均值、示例-people列表

Sorted lists: 示例-address  book

Linked list: 示例-book reader

Circular-linked lists: 实现、示例-spin the  wheel

// Chapter 2     Arrays and Lists     
// 2.1 环形链表
			Press [Enter] to start or any other to exit.
			Geography
			People
			Technology
			Nature
			Science
			Sport
			Culture
			History
			Geography
			People
			Technology
			Nature
			Science
			Sport
			Culture
			History
			Geography
			People
			Technology
			Nature
			Science
			Sport
			Culture
			History
			Press [Enter] to start or any other to exit.
/* CircularLinkedList.cs 环形链表类定义*/
using System.Collections;
using System.Collections.Generic;

namespace CircularLinkedList
{
    public class CircularLinkedList<T> : LinkedList<T> //环形链表
    {
        public new IEnumerator GetEnumerator() 
        {
            return new CircularLinkedListEnumerator<T>(this);
        }
    }
}
/*CircularLinkedListEnumerator.cs 环形链表枚举器定义*/
using System.Collections;
using System.Collections.Generic;

namespace CircularLinkedList
{
    public class CircularLinkedListEnumerator<T> : IEnumerator<T> //支持在泛型集合上进行简单迭代
    {
        private LinkedListNode<T> _current; //链表节点
        public T Current => _current.Value; //节点值
        object IEnumerator.Current => Current;//当前迭代值

        public CircularLinkedListEnumerator(LinkedList<T> list)
        {
            _current = list.First; //获取迭代当前值  链表首值
        }

        public bool MoveNext() //获取下一个值
        {
            if (_current == null)
            {
                return false;
            }
            /*  ?? 和 ??= 运算符 - Null 合并操作符
             如果左操作数的值不为 null,则 null 合并运算符 ?? 返回该值;否则,它会计算右操作数并返回其结果。
            如果左操作数的计算结果为非 null,则 ?? 运算符不会计算其右操作数。
            仅当左操作数的计算结果为 null 时,Null 合并赋值运算符 ??= 才会将其右操作数的值赋值给其左操作数。
            如果左操作数的计算结果为非 null,则 ??= 运算符不会计算其右操作数
             */
            _current = _current.Next ?? _current.List.First;
            return true;
        }
        //重置当前值
        public void Reset()
        {
            _current = _current.List.First;
        }

        public void Dispose()
        {
        }
    }
}
/*CircularLinkedListExtensions.cs 环形链表扩展类 */
using System.Collections.Generic;

namespace CircularLinkedList
{
    public static class CircularLinkedListExtensions //环形链表扩展
    {
        public static LinkedListNode<T> Next<T>(this LinkedListNode<T> node) //获取链表的下一个节点
        {
            if (node != null && node.List != null) //链表非空,节点所属链表非空
            {
                return node.Next ?? node.List.First;
            }
            return null;
        }

        public static LinkedListNode<T> Previous<T>(this LinkedListNode<T> node)//前一链表节点  
        {
            if (node != null && node.List != null)
            {
                return node.Previous ?? node.List.Last;//前一节点
            }
            return null;
        }
    }
}
/* Main程序 */
using System;
using System.Threading;

namespace CircularLinkedList
{
    class Program
    {
        static void Main(string[] args)
        {
            CircularLinkedList<string> categories = new CircularLinkedList<string>();//环形链表
            categories.AddLast("Sport");//添加节点
            categories.AddLast("Culture");
            categories.AddLast("History");
            categories.AddLast("Geography");
            categories.AddLast("People");
            categories.AddLast("Technology");
            categories.AddLast("Nature");
            categories.AddLast("Science");

            Random random = new Random();
            int totalTime = 0;//总时间
            int remainingTime = 0;//剩余时间
            foreach (string category in categories) //遍历字符串链表节点
            {   //起初执行一次,之后等remainingTime<=0后再次判断
                if (remainingTime <= 0)
                {
                    Console.WriteLine("Press [Enter] to start or any other to exit.");
                    switch (Console.ReadKey().Key)
                    {
                        case ConsoleKey.Enter:
                            totalTime = random.Next(1000, 5000);
                            remainingTime = totalTime;
                            break;
                        default:
                            return;
                    }
                }

                int categoryTime = (-450 * remainingTime) / (totalTime - 50) + 500 + (22500 / (totalTime - 50));
                remainingTime -= categoryTime;
                Thread.Sleep(categoryTime);

                Console.ForegroundColor = remainingTime <= 0 ? ConsoleColor.Red : ConsoleColor.Gray;//前景颜色:红/灰
                Console.WriteLine(category);
                Console.ForegroundColor = ConsoleColor.Gray; //前景颜色:灰色
            }
            Console.ReadLine();
        }
    }
}

//  2.2 JaggedArrays   锯齿状数组   数组第二维数量变化
			January:   W B C W C C S S W C S B B S C W S B C S S B S W W C C W C S C
			February:  W B W B W W B B C U C W C B U S C U C W W C B U C C U W
			March:     C W B S U W S W W W C C B C W U S B U U B B W B W B U W C B S
			April:     W S W B U S B S C C U S C U W U B C U W S B C U U C C S B B
			May:       B W U S C S B S B B W U C C U C B U W U S B W W C U S S U C S
			June:      C B S S S U B C U S U S B W C S W C U U B B S U W W U U W C
			July:      U C S C W S B B W B W U S B U U C W W B B S C W W U U C S S W
			August:    U C U U C W S C B B C U S U U C B C B W S S C U B C B C S C S
			September: U U B S C C U C U S B C C S U S B B C S C B B S W C W B W U
			October:   S B B C W W B B C W S W S U W U C W U S C S U S S S B U B C U
			November:  B U W C W S W B U W W S U C U U S S B W C U U U W S C B U U
			December:  S C W B B S S C C W C U W B C W C U C U C W C C U U W B C S S
/* 交通工具枚举 TransportEnum.cs */
namespace JaggedArrays
{
    public enum TransportEnum
    {
        CAR,
        BUS,
        SUBWAY,
        BIKE,
        WALK
    }
}
/* TransportEnumExtensions.cs  交通工具枚举扩展类 */
using System;

namespace JaggedArrays
{
    public static class TransportEnumExtensions //交通工具枚举扩展类
    {
        public static char GetChar(this TransportEnum transport)//获取交通工具枚举的简写字符 
        {
            switch (transport)
            {
                case TransportEnum.BIKE: return 'B';
                case TransportEnum.BUS: return 'U';
                case TransportEnum.CAR: return 'C';
                case TransportEnum.SUBWAY: return 'S';
                case TransportEnum.WALK: return 'W';
                default: throw new Exception("Unknown transport");
            }
        }

        public static ConsoleColor GetColor(this TransportEnum transport) //获取交通工具枚举对象的颜色
        {
            switch (transport)
            {
                case TransportEnum.BIKE: return ConsoleColor.Blue;
                case TransportEnum.BUS: return ConsoleColor.DarkGreen;
                case TransportEnum.CAR: return ConsoleColor.Red;
                case TransportEnum.SUBWAY: return ConsoleColor.DarkMagenta;
                case TransportEnum.WALK: return ConsoleColor.DarkYellow;
                default: throw new Exception("Unknown transport");
            }
        }
    }
}
/* Main 程序 */
using System;
using System.Globalization;
using System.Linq;

namespace JaggedArrays //锯齿数组   数组第二维数量变化
{
    class Program
    {
        static void Main(string[] args)
        {
            Random random = new Random();
            int transportTypesCount = Enum.GetNames(typeof(TransportEnum)).Length;//检索指定枚举中的常量名称的数组  的长度
            TransportEnum[][] transport = new TransportEnum[12][]; //12行 N列

            for (int month = 1; month <= 12; month++) //12个月//每天指定一随机类型交通工具
            {
                int daysCount = DateTime.DaysInMonth(DateTime.Now.Year, month);//返回指定月份和年份中的天数。
                transport[month - 1] = new TransportEnum[daysCount];//每天指定一辆交通工具
                for (int day = 1; day <= daysCount; day++) //
                {
                    int randomType = random.Next(transportTypesCount);//随机交通工具类型
                    transport[month - 1][day - 1] = (TransportEnum)randomType;//每天指定一随机类型交通工具
                }
            }

            string[] monthNames = GetMonthNames(); //获取月份名
            int monthNamesPart = monthNames.Max(n => n.Length) + 2; //取最长月份名长度+2  作为月份名显示部分长度
            for (int month = 1; month <= transport.Length; month++) //遍历每个月
            {
                Console.Write($"{monthNames[month - 1]}:".PadRight(monthNamesPart));//右侧填充空格补齐字符串长度
                for (int day = 1; day <= transport[month - 1].Length; day++)//遍历每天
                {
                    Console.ForegroundColor = ConsoleColor.White; //默认前景白色
                    Console.BackgroundColor = transport[month - 1][day - 1].GetColor();//获取车辆颜色
                    Console.Write(transport[month - 1][day - 1].GetChar());//车辆字符简称

                    Console.BackgroundColor = ConsoleColor.Black;//背景黑色
                    Console.ForegroundColor = ConsoleColor.Gray;//前景灰色
                    Console.Write(" ");//空格
                }
                Console.WriteLine();
            }
            Console.ReadLine();
        }

        private static string[] GetMonthNames() //获取月份名称
        {
            string[] names = new string[12];
            for (int month = 1; month <= 12; month++)
            {
                DateTime firstDay = new DateTime(DateTime.Now.Year, month, 1); //当年,每月第一天
                string name = firstDay.ToString("MMMM", CultureInfo.CreateSpecificCulture("en"));
                names[month - 1] = name;
            }
            return names;
        }
    }
}


/  2.3 LinkedLists  链表  通过按键遍历链表
                                          - 1 -

Nowadays, there are various (...)

Quote from "Windows Application Development Cookbook" by Marcin Jamro,
published by Packt Publishing in 2016.

                                                                                [N] NEXT >

……
                                          - 5 -

While developing applications (...)

Quote from "Windows Application Development Cookbook" by Marcin Jamro,
published by Packt Publishing in 2016.

< PREVIOUS [P]                                                                  [N] NEXT >


/* Page.cs  页 */
using System;

namespace LinkedLists
{
    public class Page
    {
        public string Content { get; set; }
    }
}

/* Main 程序 */
using System;
using System.Collections.Generic;

namespace LinkedLists
{
    class Program
    {
        static void Main(string[] args)
        {   //实例化 5 页
            Page pageFirst = new Page() { Content = "Nowadays, there are various (...)" };
            Page pageSecond = new Page() { Content = "Application development is (...)" };
            Page pageThird = new Page() { Content = "A lot of applications (...)" };
            Page pageFourth = new Page() { Content = "Do you know that modern (...)" };
            Page pageFifth = new Page() { Content = "While developing applications (...)" };
            Page pageSixth = new Page() { Content = "Could you imagine your (...)" };

            LinkedList<Page> pages = new LinkedList<Page>(); //页的链表
            pages.AddLast(pageSecond);//在链表结尾处添加包含指定值的新节点
            LinkedListNode<Page> nodePageFourth = pages.AddLast(pageFourth); //第4页 链表节点
            pages.AddLast(pageSixth);
            pages.AddFirst(pageFirst);//在链表开头处添加包含指定值的新节点
            pages.AddBefore(nodePageFourth, pageThird);//在链表中指定的现有节点前添加包含指定值的新节点
            pages.AddAfter(nodePageFourth, pageFifth);//在链表中指定的现有节点后添加包含指定值的新节点

            LinkedListNode<Page> current = pages.First;//获取链表的首节点
            int number = 1;//页码
            while (current != null)
            {
                Console.Clear();
                string numberString = $"- {number} -";
                int leadingSpaces = (90 - numberString.Length) / 2;
                Console.WriteLine(numberString.PadLeft(leadingSpaces + numberString.Length));//页码居中,全长90字符,其它补齐空格
                Console.WriteLine();

                string content = current.Value.Content; //获取当前节点内容
                for (int i = 0; i < content.Length; i += 90)//每行最多90个字符输出内容
                {
                    string line = content.Substring(i);
                    line = line.Length > 90 ? line.Substring(0, 90) : line;
                    Console.WriteLine(line);
                }

                Console.WriteLine();
                Console.WriteLine($"Quote from \"Windows Application Development Cookbook\" by Marcin Jamro,{Environment.NewLine}published by Packt Publishing in 2016.");

                Console.WriteLine();
                Console.Write(current.Previous != null ? "< PREVIOUS [P]" : GetSpaces(14));
                Console.Write(current.Next != null ? "[N] NEXT >".PadLeft(76) : string.Empty);
                Console.WriteLine();

                switch (Console.ReadKey(true).Key)//通过按键来遍历链表
                {
                    case ConsoleKey.N:
                        if (current.Next != null)
                        {
                            current = current.Next;
                            number++;
                        }
                        break;
                    case ConsoleKey.P:
                        if (current.Previous != null)
                        {
                            current = current.Previous;
                            number--;
                        }
                        break;
                    default:
                        return;
                }
            }
        }

        private static string GetSpaces(int number)
        {
            string result = string.Empty;
            for (int i = 0; i < number; i++)
            {
                result += " ";
            }
            return result;
        }
    }
}


/  2.4  多维数组 MultiDimensionalArrays01
			   1   2   3   4   5   6   7   8   9  10
			   2   4   6   8  10  12  14  16  18  20
			   3   6   9  12  15  18  21  24  27  30
			   4   8  12  16  20  24  28  32  36  40
			   5  10  15  20  25  30  35  40  45  50
			   6  12  18  24  30  36  42  48  54  60
			   7  14  21  28  35  42  49  56  63  70
			   8  16  24  32  40  48  56  64  72  80
			   9  18  27  36  45  54  63  72  81  90
			  10  20  30  40  50  60  70  80  90 100
/* Main  程序*/
using System;

namespace MultiDimensionalArrays01
{
    class Program
    {
        static void Main(string[] args)
        {
            int[,] results = new int[10, 10];//二维数组

            for (int i = 0; i < results.GetLength(0); i++)
            {
                for (int j = 0; j < results.GetLength(1); j++)
                {
                    results[i, j] = (i + 1) * (j + 1);
                }
            }

            for (int i = 0; i < results.GetLength(0); i++)
            {
                for (int j = 0; j < results.GetLength(1); j++)
                {
                    Console.Write("{0,4}", results[i, j]);
                }
                Console.WriteLine();
            }
            Console.ReadLine();
        }  
    }
}


  2.5  多维数组   MultidimensionalArrays02
					○ ○ ○ ○ “ “ “ “ “ “
					○ ○ ○ ○ “ “ “ “ “ “
					○ ○ ○ ○ “ “ “ “ “ “
					○ ○ ○ ○ “ “ “ “ “ “
					○ ○ ○ ○ ○ ○ ○ ● ● ●
					○ ○ ○ ○ ○ ○ ○ ● ○ ○
					○ ○ ○ ○ ○ ○ ○ ● ○ ○
					≈ ≈ ≈ ≈ ≈ ≈ ≈ ● ○ ○
					≈ ≈ ≈ ≈ ≈ ≈ ≈ ● ○ ○
					≈ ≈ ≈ ≈ ≈ ≈ ≈ ● ≈ ≈
					≈ ≈ ≈ ≈ ≈ ≈ ≈ ● ≈ ≈

/* 地形枚举 */
namespace MultiDimensionalArrays02
{//草, 沙, 水, 墙
    public enum TerrainEnum
    {
        GRASS,
        SAND,
        WATER,
        WALL
    }
}

/* 地形枚举扩展类 TerrainEnumExtensions.cs */
using System;

namespace MultiDimensionalArrays02
{
    public static class TerrainEnumExtensions //地形枚举扩展
    {
        public static ConsoleColor GetColor(this TerrainEnum terrain) //获取地形颜色
        {
            switch (terrain)
            {
                case TerrainEnum.GRASS: return ConsoleColor.Green;
                case TerrainEnum.SAND: return ConsoleColor.Yellow;
                case TerrainEnum.WATER: return ConsoleColor.Blue;
                default: return ConsoleColor.DarkGray;
            }
        }

        public static char GetChar(this TerrainEnum terrain) //获取地形简写字符
        {
            switch (terrain)
            {
                case TerrainEnum.GRASS: return '\u201c';
                case TerrainEnum.SAND: return '\u25cb';
                case TerrainEnum.WATER: return '\u2248';
                default: return '\u25cf';
            }
        }
    }
}

/*  多维度数组 Main 程序 */
using System;
using System.Text;

namespace MultiDimensionalArrays02
{
    class Program
    {
        static void Main(string[] args)
        {   //地形图
            TerrainEnum[,] map =
            {
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS, TerrainEnum.GRASS },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.WALL, TerrainEnum.WALL, TerrainEnum.WALL },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.WALL, TerrainEnum.SAND, TerrainEnum.SAND },
                { TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.SAND, TerrainEnum.WALL, TerrainEnum.SAND, TerrainEnum.SAND },
                { TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WALL, TerrainEnum.SAND, TerrainEnum.SAND },
                { TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WALL, TerrainEnum.SAND, TerrainEnum.SAND },
                { TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WALL, TerrainEnum.WATER, TerrainEnum.WATER },
                { TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WATER, TerrainEnum.WALL, TerrainEnum.WATER, TerrainEnum.WATER }
            };

            Console.OutputEncoding = UTF8Encoding.UTF8; //控制台输出编码: UTF8
            for (int row = 0; row < map.GetLength(0); row++) //遍历地形图的行
            {
                for (int column = 0; column < map.GetLength(1); column++) //遍历地形图的列
                {
                    Console.ForegroundColor = map[row, column].GetColor(); //获取地形上每点颜色,设置为前景色
                    Console.Write(map[row, column].GetChar() + " ");//控制台输出地形点的简写字符
                }
                Console.WriteLine();//下一行
            }

            Console.ForegroundColor = ConsoleColor.Gray;//恢复灰色前景
			Console.ReadLine();
        }
    }
}


///   2.6  简单列表 SimpleLists01  
				Enter the number: 3.25
				The average value: 3.25
				Enter the number: 53.2
				The average value: 28.225
				Enter the number: 55.6
				The average value: 37.35
				Enter the number:

/* Main 程序 */
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;

namespace SimpleLists01
{
    class Program
    {
        static void Main(string[] args)
        {
            List<double> numbers = new List<double>();
            do
            {
                Console.Write("Enter the number: ");
                string numberString = Console.ReadLine(); //输入字符串
                if (!double.TryParse(numberString, NumberStyles.Float, new NumberFormatInfo(), out double number))//解析为双精度浮点型
                {
                    break;
                }

                numbers.Add(number);//添加到列表
                Console.WriteLine($"The average value: {numbers.Average()}");//输出平均值
            }
            while (true);
        }
    }
}


//  2.7  SimpleLists02  简单列表
			Ann (31 years) from PL.
			Caroline (21 years) from UK.
			John (21 years) from UK.
			Marcin (29 years) from PL.
			Nick (28 years) from DE.
			Sabine (25 years) from DE.

/* 城市枚举 CountryEnum.cs */
namespace SimpleLists02
{
    public enum CountryEnum
    {
        PL,
        UK,
        DE
    }
}

/*人 枚举  Person.cs */
namespace SimpleLists02
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public CountryEnum Country { get; set; }
    }
}

/* Main  程序 */
using System;
using System.Collections.Generic;
using System.Linq;

namespace SimpleLists02
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Person> people = new List<Person>();//人列表
            people.Add(new Person() { Name = "Marcin", Country = CountryEnum.PL, Age = 29 });
            people.Add(new Person() { Name = "Sabine", Country = CountryEnum.DE, Age = 25 });
            people.Add(new Person() { Name = "Caroline", Country = CountryEnum.UK, Age = 21 });
            people.Add(new Person() { Name = "John", Country = CountryEnum.UK, Age = 21 });
            people.Add(new Person() { Name = "Nick", Country = CountryEnum.DE, Age = 28 });
            people.Add(new Person() { Name = "Ann", Country = CountryEnum.PL, Age = 31 });

            List<Person> results = people.OrderBy(p => p.Name).ToList();//按照人的名称排序 
            foreach (Person person in results)//输出
            {
                Console.WriteLine($"{person.Name} ({person.Age} years) from {person.Country}.");
            }
        }
    }
}

/   2.8 SingleDimensionalArrays 简单维度数组 
		-> January
		-> February
		-> March
		-> April
		-> May
		-> June
		-> July
		-> August
		-> September
		-> October
		-> November
		-> December
/*Main 程序 */
using System;
using System.Globalization;

namespace SingleDimensionalArrays
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] months = new string[12];//

            for (int month = 1; month <= 12; month++)
            {
                DateTime firstDay = new DateTime(DateTime.Now.Year, month, 1);//每月第一天
                string name = firstDay.ToString("MMMM", CultureInfo.CreateSpecificCulture("en"));
                months[month - 1] = name;
            }

            foreach (string month in months)//输出每月名称
            {
                Console.WriteLine($"-> {month}");
            }
            Console.ReadLine();
        }
    }
}

//   2.9   自动排序的列表 SortedList  
			Ann (31 years) from PL.
			Caroline (21 years) from UK.
			John (21 years) from UK.
			Marcin (29 years) from PL.
			Nick (28 years) from DE.
			Sabine (25 years) from DE.

/* Main程序 ( 城市枚举,人的类定义 略) */
using System;
using System.Collections.Generic;

namespace SortedLists
{
    class Program
    {
        static void Main(string[] args)
        {
            SortedList<string, Person> people = new SortedList<string, Person>();
            people.Add("Marcin", new Person() { Name = "Marcin", Country = CountryEnum.PL, Age = 29 });
            people.Add("Sabine", new Person() { Name = "Sabine", Country = CountryEnum.DE, Age = 25 });
            people.Add("Caroline", new Person() { Name = "Caroline", Country = CountryEnum.UK, Age = 21 });
            people.Add("John", new Person() { Name = "John", Country = CountryEnum.UK, Age = 21 });
            people.Add("Nick", new Person() { Name = "Nick", Country = CountryEnum.DE, Age = 28 });
            people.Add("Ann", new Person() { Name = "Ann", Country = CountryEnum.PL, Age = 31 });

            foreach (KeyValuePair<string, Person> person in people)
            {
                Console.WriteLine($"{person.Value.Name} ({person.Value.Age} years) from {person.Value.Country}.");
            }
            Console.ReadLine();
        }
    }
}



/  2.10  排序算法  SortingAlgorithms 
				SELECTION SORT
				-42 | -11 | -9 | 0 | 1 | 6 | 12 | 68 | 90
				-42.59 | -11.2 | -9.8 | 0 | 1.1 | 6.1 | 12.56 | 68.68 | 90.9
				Ann | George | James | Marcin | Mary | Nicole

				INSERTION SORT
				-42 | -11 | -9 | 0 | 1 | 6 | 12 | 68 | 90
				-42.59 | -11.2 | -9.8 | 0 | 1.1 | 6.1 | 12.56 | 68.68 | 90.9
				Ann | George | James | Marcin | Mary | Nicole

				BUBBLE SORT
				-42 | -11 | -9 | 0 | 1 | 6 | 12 | 68 | 90
				-42.59 | -11.2 | -9.8 | 0 | 1.1 | 6.1 | 12.56 | 68.68 | 90.9
				Ann | George | James | Marcin | Mary | Nicole

				QUICKSORT
				-42 | -11 | -9 | 0 | 1 | 6 | 12 | 68 | 90
				-42.59 | -11.2 | -9.8 | 0 | 1.1 | 6.1 | 12.56 | 68.68 | 90.9
				Ann | George | James | Marcin | Mary | Nicole

/* Main 程序 */
using System.Collections.Generic;

namespace SortingAlgorithms
{
    class Program
    {
        static void Main(string[] args)
        {
            WriteHeader("SELECTION SORT", false);
            SelectionTest(); //选择排序

            WriteHeader("INSERTION SORT");
            InsertionTest();//插入排序

            WriteHeader("BUBBLE SORT");
            BubbleTest();//冒泡排序

            WriteHeader("QUICKSORT");
            QuicksortTest();//快速排序
            Console.ReadLine();
        }

        static void SelectionTest()
        {
            int[] integerValues = { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
            SelectionSort.Sort(integerValues); 
            Console.WriteLine(string.Join(" | ", integerValues));

            float[] floatValues = { -11.2f, 12.56f, -42.59f, 0.0f, 1.1f, 90.9f, 68.68f, 6.1f, -9.8f };
            SelectionSort.Sort(floatValues);
            Console.WriteLine(string.Join(" | ", floatValues));

            string[] stringValues = { "Mary", "Marcin", "Ann", "James", "George", "Nicole" };
            SelectionSort.Sort(stringValues);
            Console.WriteLine(string.Join(" | ", stringValues));
        }

        static void InsertionTest()
        {
            int[] integerValues = { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
            InsertionSort.Sort(integerValues);
            Console.WriteLine(string.Join(" | ", integerValues));

            float[] floatValues = { -11.2f, 12.56f, -42.59f, 0.0f, 1.1f, 90.9f, 68.68f, 6.1f, -9.8f };
            InsertionSort.Sort(floatValues);
            Console.WriteLine(string.Join(" | ", floatValues));

            string[] stringValues = { "Mary", "Marcin", "Ann", "James", "George", "Nicole" };
            InsertionSort.Sort(stringValues);
            Console.WriteLine(string.Join(" | ", stringValues));
        }

        static void BubbleTest()
        {
            int[] integerValues = { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
            BubbleSort.Sort(integerValues);
            Console.WriteLine(string.Join(" | ", integerValues));

            float[] floatValues = { -11.2f, 12.56f, -42.59f, 0.0f, 1.1f, 90.9f, 68.68f, 6.1f, -9.8f };
            BubbleSort.Sort(floatValues);
            Console.WriteLine(string.Join(" | ", floatValues));

            string[] stringValues = { "Mary", "Marcin", "Ann", "James", "George", "Nicole" };
            BubbleSort.Sort(stringValues);
            Console.WriteLine(string.Join(" | ", stringValues));
        }

        static void QuicksortTest()
        {
            int[] integerValues = { -11, 12, -42, 0, 1, 90, 68, 6, -9 };
            QuickSort.Sort(integerValues);
            Console.WriteLine(string.Join(" | ", integerValues));

            float[] floatValues = { -11.2f, 12.56f, -42.59f, 0.0f, 1.1f, 90.9f, 68.68f, 6.1f, -9.8f };
            QuickSort.Sort(floatValues);
            Console.WriteLine(string.Join(" | ", floatValues));

            string[] stringValues = { "Mary", "Marcin", "Ann", "James", "George", "Nicole" };
            QuickSort.Sort(stringValues);
            Console.WriteLine(string.Join(" | ", stringValues));
        }

        static void WriteHeader(string header, bool addLine = true)
        {
            Console.ForegroundColor = ConsoleColor.White;
            Console.WriteLine((addLine ? Environment.NewLine : string.Empty) + header);
            Console.ForegroundColor = ConsoleColor.Gray;
        }
    }
}

//选择排序
using System;

namespace SortingAlgorithms
{
    public static class SelectionSort //选择排序
    {
        /*
            首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置。
            再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
            重复第二步,直到所有元素均排序完毕。
        */
        public static void Sort<T>(T[] array) where T : IComparable
        {
            for (int i = 0; i < array.Length - 1; i++) //遍历数组元素
            {
                int minIndex = i; //最小值索引初始化
                T minValue = array[i];//最小值初始化
                for (int j = i + 1; j < array.Length; j++)//遍历i之后的所有值
                {
                    if (array[j].CompareTo(minValue) < 0) //找到i之后所有值中最小的值
                    {
                        minIndex = j;//更新最小值索引
                        minValue = array[j];//更新最小值
                    }
                }
                Swap(array, i, minIndex);//把最小值放在i索引位置
            }
        }
        //交换数组的两项
        private static void Swap<T>(T[] array, int first, int second)
        {
            T temp = array[first];
            array[first] = array[second];
            array[second] = temp;
        }
    }
}
//插入排序
using System;

namespace SortingAlgorithms
{
    public static class InsertionSort //插入排序
    {
        public static void Sort<T>(T[] array) where T : IComparable
        {
            for (int i = 1; i < array.Length; i++)
            {
                int j = i;
                //从索引i元素开始往前找, 索引j元素排序中先于索引j-1元素,则交换位置
                while (j > 0 && array[j].CompareTo(array[j - 1]) < 0)
                {
                    Swap(array, j, j - 1);
                    j--;
                }
            }
        }
        //交换数组两个对象
        private static void Swap<T>(T[] array, int first, int second)
        {
            T temp = array[first];
            array[first] = array[second];
            array[second] = temp;
        }
    }
}
//冒泡排序
using System;

namespace SortingAlgorithms
{
    public static class BubbleSort //冒泡排序
    {
        public static void Sort<T>(T[] array) where T : IComparable
        {
            for (int i = 0; i < array.Length; i++)
            {
                bool isAnyChange = false;
                for (int j = 0; j < array.Length - 1; j++)
                {
                    if (array[j].CompareTo(array[j + 1]) > 0) //元素j比元素j+1 靠后
                    {
                        isAnyChange = true;//需要交换
                        Swap(array, j, j + 1);
                    }
                }

                if (!isAnyChange)
                {
                    break;
                }
            }
        }
        //交换数组元素
        private static void Swap<T>(T[] array, int first, int second)
        {
            T temp = array[first];
            array[first] = array[second];
            array[second] = temp;
        }
    }
}
//快速排序
using System;

namespace SortingAlgorithms
{
    public static class QuickSort //快速排序
    {
        public static void Sort<T>(T[] array) where T : IComparable
        {
            Sort(array, 0, array.Length - 1);
        }
        //排序lower-upper索引之间的数据
        private static void Sort<T>(T[] array, int lower, int upper) where T : IComparable
        {
            if (lower < upper)
            {
                int p = Partition(array, lower, upper);
                Sort(array, lower, p);//对子数组递归调用排序算法
                Sort(array, p + 1, upper);
            }
        }
        //找到pivot的位置j(pivot之前的都是排序先于pivot的,之后的都是排序后于pivot的)
        private static int Partition<T>(T[] array, int lower, int upper) where T : IComparable
        {
            int i = lower;
            int j = upper;
            T pivot = array[lower];//数组首位引用
            // T pivot = array[(lower + upper) / 2];
            do
            {
                /*将当前实例与另一个相同类型的对象进行比较,并返回一个整数,该整数指示当前实例在排序顺序中是否先于(<0)、后于(>0)或出现在与其他对象相同(=0)的位置。*/
                while (array[i].CompareTo(pivot) < 0) { i++; }//array[i].CompareTo(pivot) >= 0跳出。   从前往后 寻找比pivot 靠后的array[i],找到后跳出while
                while (array[j].CompareTo(pivot) > 0) { j--; }//array[j].CompareTo(pivot) <= 0跳出。   从后往前 寻找比pivot 靠前的array[j], 找到后跳出while
                if (i >= j) { break; }//跳出条件 
                Swap(array, i, j); //把应该靠前的array[j]  和 应该靠后的 array[i] 交换位置
            }
            while (i <= j);
            return j;
        }
        //交换数组的两个元素   pivot始终指向存储首位元素的位置
        private static void Swap<T>(T[] array, int first, int second)
        {
            T temp = array[first];
            array[first] = array[second];
            array[second] = temp;
        }
    }
}
//static void QuickSort(int[] dataArray, int left, int right)
//{
//    if (left < right)
//    {
//        int x = dataArray;
//        int i = left;
//        int j = right;
//        while (true && i < j)
//        {
//            while (true && i < j)
//            {
//                if (dataArray[j] <= x)
//                {
//                    dataArray[i] = dataArray[j];
//                    break;
//                }
//                else
//                {
//                    j--;
//                }
//            }
//            while (true && i < j)
//            {
//                if (dataArray[i] > x)
//                {
//                    dataArray[j] = dataArray[i];
//                    break;
//                }//if结束
//                else
//                {
//                    i++;
//                }
//            }//while结束
//        }//第一个While结束

//        //跳出循环,现在i==j了,i是中间位。
//        dataArray[i] = x;
//        QuickSort(dataArray, left, i - 1);
//        QuickSort(dataArray, i + 1, right);
//    }
//}
//static void Main(string[] args)
//{
//    int[] data = new int[] { 72, 6, 57, 88, 60, 42, 83, 73, 48, 85 };
//    Console.WriteLine("快速排序的顺序为:");
//    QuickSort(data, 0, data.Length - 1);
//    foreach (var item in data)
//    {
//        Console.Write(item + " ");
//    }
//    Console.ReadLine();
//}



















猜你喜欢

转载自blog.csdn.net/cxyhjl/article/details/129666176