Windows 数据结构 - C# 示例

Windows平台C#数据结构示例,包括数组、列表、字典、队列、栈和集合

💻 数组操作和操作 csharp

🟢 simple ⭐⭐

C#中的数组创建、操作、搜索、排序和高级数组操作

⏱️ 20 min 🏷️ csharp, array, data structures, collections, windows
Prerequisites: Basic C# syntax, LINQ basics
using System;
using System.Linq;

class ArrayOperations
{
    // 1. Array declaration and initialization
    public static void ArrayBasics()
    {
        Console.WriteLine("=== Array Basics ===");

        // Different ways to create arrays
        int[] numbers1 = new int[5];                    // Array with default values
        int[] numbers2 = { 1, 2, 3, 4, 5 };            // Array initializer
        int[] numbers3 = new int[] { 10, 20, 30, 40, 50 }; // Explicit array creation

        Console.WriteLine("Default initialized array:");
        PrintArray(numbers1);

        Console.WriteLine("\nInitializer array:");
        PrintArray(numbers2);

        Console.WriteLine("\nExplicit array:");
        PrintArray(numbers3);
    }

    // 2. Multi-dimensional arrays
    public static void MultiDimensionalArrays()
    {
        Console.WriteLine("\n=== Multi-dimensional Arrays ===");

        // 2D array
        int[,] matrix2D = new int[3, 4]
        {
            { 1, 2, 3, 4 },
            { 5, 6, 7, 8 },
            { 9, 10, 11, 12 }
        };

        Console.WriteLine("2D Array (3x4):");
        for (int i = 0; i < matrix2D.GetLength(0); i++)
        {
            for (int j = 0; j < matrix2D.GetLength(1); j++)
            {
                Console.Write($"{matrix2D[i, j],3}");
            }
            Console.WriteLine();
        }

        // 3D array
        int[,,] cube3D = new int[2, 2, 2]
        {
            { { 1, 2 }, { 3, 4 } },
            { { 5, 6 }, { 7, 8 } }
        };

        Console.WriteLine("\n3D Array (2x2x2):");
        for (int x = 0; x < 2; x++)
        {
            Console.WriteLine($"Layer {x}:");
            for (int y = 0; y < 2; y++)
            {
                for (int z = 0; z < 2; z++)
                {
                    Console.Write($"{cube3D[x, y, z],3}");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
    }

    // 3. Jagged arrays (array of arrays)
    public static void JaggedArrays()
    {
        Console.WriteLine("=== Jagged Arrays ===");

        // Create jagged array
        int[][] jagged = new int[3][];
        jagged[0] = new int[] { 1, 2, 3 };
        jagged[1] = new int[] { 4, 5, 6, 7 };
        jagged[2] = new int[] { 8, 9 };

        Console.WriteLine("Jagged array:");
        for (int i = 0; i < jagged.Length; i++)
        {
            Console.Write($"Row {i}: ");
            for (int j = 0; j < jagged[i].Length; j++)
            {
                Console.Write($"{jagged[i][j]} ");
            }
            Console.WriteLine();
        }

        // Alternative initialization
        int[][] jagged2 =
        {
            new int[] { 1, 2 },
            new int[] { 3, 4, 5 },
            new int[] { 6, 7, 8, 9 }
        };

        Console.WriteLine("\nAlternative jagged array:");
        PrintJaggedArray(jagged2);
    }

    // 4. Array manipulation operations
    public static void ArrayManipulation()
    {
        Console.WriteLine("\n=== Array Manipulation ===");

        int[] numbers = { 5, 2, 8, 1, 9, 3, 7, 4, 6 };

        Console.WriteLine("Original array:");
        PrintArray(numbers);

        // Sort array
        Array.Sort(numbers);
        Console.WriteLine("\nSorted array:");
        PrintArray(numbers);

        // Reverse array
        Array.Reverse(numbers);
        Console.WriteLine("\nReversed array:");
        PrintArray(numbers);

        // Copy array
        int[] copy = new int[numbers.Length];
        Array.Copy(numbers, copy, numbers.Length);
        Console.WriteLine("\nCopied array:");
        PrintArray(copy);

        // Resize array
        Array.Resize(ref copy, 12);
        Console.WriteLine("\nResized array (to 12 elements):");
        PrintArray(copy);

        // Clear portion of array
        Array.Clear(copy, 5, 5);
        Console.WriteLine("\nArray after clearing elements 5-9:");
        PrintArray(copy);
    }

    // 5. Array searching and finding
    public static void ArraySearching()
    {
        Console.WriteLine("\n=== Array Searching ===");

        int[] numbers = { 10, 25, 30, 45, 50, 65, 80, 95, 100 };

        Console.WriteLine("Array:");
        PrintArray(numbers);

        // Linear search using built-in method
        int target = 50;
        int index = Array.IndexOf(numbers, target);
        Console.WriteLine($$"\nIndex of {target}: {index}");

        // Find all elements greater than 50
        var greaterThan50 = numbers.Where(n => n > 50).ToArray();
        Console.WriteLine($"Elements greater than 50: [{string.Join(", ", greaterThan50)}]");

        // Binary search (requires sorted array)
        Array.Sort(numbers);
        int binaryIndex = Array.BinarySearch(numbers, 65);
        Console.WriteLine($"\nBinary search for 65 in sorted array: {binaryIndex}");

        // Find min and max
        int min = numbers.Min();
        int max = numbers.Max();
        Console.WriteLine($"Min: {min}, Max: {max}");
    }

    // 6. Advanced array operations
    public static void AdvancedArrayOperations()
    {
        Console.WriteLine("\n=== Advanced Array Operations ===");

        // Create arrays for demonstration
        int[] array1 = { 1, 2, 3, 4, 5 };
        int[] array2 = { 4, 5, 6, 7, 8 };

        Console.WriteLine("Array 1:");
        PrintArray(array1);
        Console.WriteLine("Array 2:");
        PrintArray(array2);

        // Array operations with LINQ
        var union = array1.Union(array2).ToArray();
        Console.WriteLine($"
Union: [{string.Join(", ", union)}]");

        var intersection = array1.Intersect(array2).ToArray();
        Console.WriteLine($"Intersection: [{string.Join(", ", intersection)}]");

        var difference = array1.Except(array2).ToArray();
        Console.WriteLine($"Array1 - Array2: [{string.Join(", ", difference)}]");

        var concat = array1.Concat(array2).ToArray();
        Console.WriteLine($"Concatenation: [{string.Join(", ", concat)}]");

        // Distinct elements
        int[] withDuplicates = { 1, 2, 2, 3, 3, 3, 4, 5 };
        var distinct = withDuplicates.Distinct().ToArray();
        Console.WriteLine($"\nOriginal with duplicates: [{string.Join(", ", withDuplicates)}]");
        Console.WriteLine($"Distinct: [{string.Join(", ", distinct)}]");
    }

    // 7. Array projection and transformation
    public static void ArrayTransformation()
    {
        Console.WriteLine("\n=== Array Transformation ===");

        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        Console.WriteLine("Original array:");
        PrintArray(numbers);

        // Square each element
        var squares = numbers.Select(n => n * n).ToArray();
        Console.WriteLine($"\nSquares: [{string.Join(", ", squares)}]");

        // Even numbers only
        var evens = numbers.Where(n => n % 2 == 0).ToArray();
        Console.WriteLine($"Even numbers: [{string.Join(", ", evens)}]");

        // Group by parity
        var grouped = numbers.GroupBy(n => n % 2)
                            .ToDictionary(g => g.Key == 0 ? "Even" : "Odd", g => g.ToArray());

        Console.WriteLine("\nGrouped by parity:");
        foreach (var group in grouped)
        {
            Console.WriteLine($"{group.Key}: [{string.Join(", ", group.Value)}]");
        }

        // Calculate statistics
        double sum = numbers.Sum();
        double average = numbers.Average();
        int count = numbers.Count();

        Console.WriteLine($"\nStatistics:");
        Console.WriteLine($"Count: {count}");
        Console.WriteLine($"Sum: {sum}");
        Console.WriteLine($"Average: {average:F2}");
    }

    // 8. Array performance considerations
    public static void ArrayPerformance()
    {
        Console.WriteLine("\n=== Array Performance Considerations ===");

        const int size = 1000000;
        int[] largeArray = new int[size];

        // Initialize with random numbers
        Random random = new Random();
        for (int i = 0; i < size; i++)
        {
            largeArray[i] = random.Next(1000);
        }

        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Measure sorting performance
        stopwatch.Restart();
        Array.Sort(largeArray);
        stopwatch.Stop();
        Console.WriteLine($"Sorting {size:N0} elements took {stopwatch.ElapsedMilliseconds}ms");

        // Measure binary search performance
        stopwatch.Restart();
        int foundIndex = Array.BinarySearch(largeArray, 500);
        stopwatch.Stop();
        Console.WriteLine($"Binary search took {stopwatch.ElapsedTicks} ticks");

        // Measure LINQ performance
        stopwatch.Restart();
        var filtered = largeArray.Where(n => n > 500).Take(10).ToArray();
        stopwatch.Stop();
        Console.WriteLine($"LINQ filtering took {stopwatch.ElapsedMilliseconds}ms");
    }

    // 9. Working with strings as arrays
    public static void StringArrays()
    {
        Console.WriteLine("\n=== String Arrays ===");

        // String array operations
        string[] words = { "apple", "banana", "cherry", "date", "elderberry" };

        Console.WriteLine("String array:");
        PrintArray(words);

        // Sort strings
        Array.Sort(words);
        Console.WriteLine("\nSorted strings:");
        PrintArray(words);

        // Find strings starting with specific letter
        var startsWithB = words.Where(w => w.StartsWith("b", StringComparison.OrdinalIgnoreCase)).ToArray();
        Console.WriteLine($"\nWords starting with 'B': [{string.Join(", ", startsWithB)}]");

        // String length analysis
        var lengthAnalysis = words.ToDictionary(w => w, w => w.Length);
        Console.WriteLine("\nLength analysis:");
        foreach (var kvp in lengthAnalysis)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value} characters");
        }
    }

    // 10. Custom array helper methods
    public static void CustomArrayHelpers()
    {
        Console.WriteLine("\n=== Custom Array Helpers ===");

        int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        Console.WriteLine("Original array:");
        PrintArray(numbers);

        // Custom bubble sort
        int[] bubbleSorted = (int[])numbers.Clone();
        BubbleSort(bubbleSorted);
        Console.WriteLine("\nBubble sorted:");
        PrintArray(bubbleSorted);

        // Custom reverse
        int[] reversed = (int[])numbers.Clone();
        ReverseArray(reversed);
        Console.WriteLine("\nReversed:");
        PrintArray(reversed);

        // Find subarray
        int[] subArray = FindSubArray(numbers, 3, 6);
        Console.WriteLine("\nSubarray (elements 3-5):");
        PrintArray(subArray);

        // Rotate array
        int[] rotated = RotateArray(numbers, 3);
        Console.WriteLine("\nRotated (left by 3):");
        PrintArray(rotated);
    }

    // Helper methods
    static void PrintArray<T>(T[] array)
    {
        Console.WriteLine($"[{string.Join(", ", array)}]");
    }

    static void PrintJaggedArray<T>(T[][] jaggedArray)
    {
        for (int i = 0; i < jaggedArray.Length; i++)
        {
            Console.Write($"Row {i}: [");
            for (int j = 0; j < jaggedArray[i].Length; j++)
            {
                Console.Write(jaggedArray[i][j]);
                if (j < jaggedArray[i].Length - 1) Console.Write(", ");
            }
            Console.WriteLine("]");
        }
    }

    static void BubbleSort<T>(T[] array) where T : IComparable<T>
    {
        for (int i = 0; i < array.Length - 1; i++)
        {
            for (int j = 0; j < array.Length - i - 1; j++)
            {
                if (array[j].CompareTo(array[j + 1]) > 0)
                {
                    T temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }

    static void ReverseArray<T>(T[] array)
    {
        for (int i = 0; i < array.Length / 2; i++)
        {
            T temp = array[i];
            array[i] = array[array.Length - 1 - i];
            array[array.Length - 1 - i] = temp;
        }
    }

    static T[] FindSubArray<T>(T[] array, int start, int end)
    {
        if (start < 0 || end >= array.Length || start > end)
        {
            return new T[0];
        }

        int length = end - start + 1;
        T[] subArray = new T[length];
        Array.Copy(array, start, subArray, 0, length);
        return subArray;
    }

    static T[] RotateArray<T>(T[] array, int positions)
    {
        if (array == null || array.Length == 0)
            return array;

        positions = positions % array.Length;
        if (positions < 0)
            positions += array.Length;

        T[] rotated = new T[array.Length];
        for (int i = 0; i < array.Length; i++)
        {
            rotated[i] = array[(i + positions) % array.Length];
        }

        return rotated;
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# Array Operations Demo ===\n");

        try
        {
            ArrayBasics();
            MultiDimensionalArrays();
            JaggedArrays();
            ArrayManipulation();
            ArraySearching();
            AdvancedArrayOperations();
            ArrayTransformation();
            ArrayPerformance();
            StringArrays();
            CustomArrayHelpers();

            Console.WriteLine("\nAll array operation examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in array demo: {ex.Message}");
        }
    }
}

💻 哈希表和字典操作 csharp

🟢 simple ⭐⭐

不同数据类型和用例的字典、哈希表和键值对操作

⏱️ 25 min 🏷️ csharp, dictionary, hashtable, data structures, windows
Prerequisites: Basic C# collections, Generic types
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;

class HashtableOperations
{
    // 1. Dictionary operations
    public static void DictionaryBasics()
    {
        Console.WriteLine("=== Dictionary Basics ===");

        // Create dictionary with string keys and int values
        Dictionary<string, int> studentGrades = new Dictionary<string, int>
        {
            { "Alice", 85 },
            { "Bob", 92 },
            { "Charlie", 78 }
        };

        Console.WriteLine("Initial dictionary:");
        PrintDictionary(studentGrades);

        // Add new items
        studentGrades.Add("David", 90);
        studentGrades["Eve"] = 88; // Alternative way to add

        Console.WriteLine("\nAfter adding new students:");
        PrintDictionary(studentGrades);

        // Access values
        Console.WriteLine($"\nAlice's grade: {studentGrades["Alice"]}");

        // TryGetValue (safe access)
        if (studentGrades.TryGetValue("Frank", out int franksGrade))
        {
            Console.WriteLine($"Frank's grade: {franksGrade}");
        }
        else
        {
            Console.WriteLine("Frank is not in the dictionary");
        }

        // Update value
        studentGrades["Alice"] = 87;
        Console.WriteLine($"\nAlice's updated grade: {studentGrades["Alice"]}");
    }

    // 2. Dictionary with different data types
    public static void DictionaryWithDifferentTypes()
    {
        Console.WriteLine("\n=== Dictionary with Different Types ===");

        // Dictionary with int keys and string values
        Dictionary<int, string> months = new Dictionary<int, string>
        {
            { 1, "January" },
            { 2, "February" },
            { 3, "March" },
            { 4, "April" },
            { 5, "May" },
            { 6, "June" }
        };

        Console.WriteLine("Months dictionary:");
        foreach (var month in months)
        {
            Console.WriteLine($"{month.Key}: {month.Value}");
        }

        // Dictionary with custom object keys
        Dictionary<Person, string> employeeRoles = new Dictionary<Person, string>
        {
            { new Person { Id = 1, Name = "John Doe" }, "Developer" },
            { new Person { Id = 2, Name = "Jane Smith" }, "Designer" }
        };

        Console.WriteLine("\nEmployee roles:");
        foreach (var employee in employeeRoles)
        {
            Console.WriteLine($"{employee.Key.Name}: {employee.Value}");
        }
    }

    // 3. Hashtable operations (non-generic)
    public static void HashtableBasics()
    {
        Console.WriteLine("\n=== Hashtable Basics ===");

        Hashtable inventory = new Hashtable();

        // Add items
        inventory.Add("Laptop", 15);
        inventory.Add("Mouse", 50);
        inventory.Add("Keyboard", 30);

        // Alternative ways to add
        inventory["Monitor"] = 20;
        inventory["Printer"] = 10;

        Console.WriteLine("Inventory hashtable:");
        foreach (DictionaryEntry item in inventory)
        {
            Console.WriteLine($"{item.Key}: {item.Value}");
        }

        // Access values
        Console.WriteLine($$"\nNumber of laptops: {inventory["Laptop"]}");

        // Check if key exists
        Console.WriteLine($"Contains 'Mouse': {inventory.ContainsKey("Mouse")}");
        Console.WriteLine($"Contains 'Tablet': {inventory.ContainsKey("Tablet")}");

        // Remove item
        inventory.Remove("Printer");
        Console.WriteLine("\nAfter removing Printer:");
        foreach (DictionaryEntry item in inventory)
        {
            Console.WriteLine($"{item.Key}: {item.Value}");
        }
    }

    // 4. Dictionary operations and methods
    public static void DictionaryOperations()
    {
        Console.WriteLine("\n=== Dictionary Operations ===");

        Dictionary<string, List<string>> wordGroups = new Dictionary<string, List<string>>
        {
            { "Fruits", new List<string> { "Apple", "Banana", "Orange" } },
            { "Colors", new List<string> { "Red", "Green", "Blue" } },
            { "Animals", new List<string> { "Dog", "Cat", "Bird" } }
        };

        Console.WriteLine("Word groups:");
        PrintNestedDictionary(wordGroups);

        // Add to existing list
        wordGroups["Fruits"].Add("Grape");
        wordGroups["Colors"].Add("Yellow");

        // Add new category
        wordGroups["Vehicles"] = new List<string> { "Car", "Bike", "Bus" };

        Console.WriteLine("\nUpdated word groups:");
        PrintNestedDictionary(wordGroups);

        // Remove specific item from list
        wordGroups["Colors"].Remove("Red");
        Console.WriteLine("\nAfter removing 'Red' from Colors:");

        // Dictionary methods
        Console.WriteLine($"Total categories: {wordGroups.Count}");
        Console.WriteLine($"Contains 'Animals': {wordGroups.ContainsKey("Animals")}");
        Console.WriteLine($"Contains 'Vegetables': {wordGroups.ContainsKey("Vegetables")}");

        // Get keys and values
        Console.WriteLine("\nAll categories:");
        foreach (string key in wordGroups.Keys)
        {
            Console.WriteLine(key);
        }
    }

    // 5. Dictionary searching and filtering
    public static void DictionarySearching()
    {
        Console.WriteLine("\n=== Dictionary Searching ===");

        Dictionary<string, double> productPrices = new Dictionary<string, double>
        {
            { "Laptop", 999.99 },
            { "Mouse", 25.50 },
            { "Keyboard", 75.00 },
            { "Monitor", 299.99 },
            { "Headphones", 149.99 },
            { "USB Cable", 12.99 },
            { "Webcam", 89.99 }
        };

        Console.WriteLine("Product prices:");
        PrintDictionary(productPrices);

        // Find expensive products (price > 100)
        var expensiveProducts = productPrices.Where(kvp => kvp.Value > 100)
                                          .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

        Console.WriteLine("\nExpensive products (> $100):");
        PrintDictionary(expensiveProducts);

        // Find products with specific names
        var productsStartingWithM = productPrices.Where(kvp => kvp.Key.StartsWith("M"))
                                              .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

        Console.WriteLine("\nProducts starting with 'M':");
        PrintDictionary(productsStartingWithM);

        // Calculate total value
        double totalValue = productPrices.Values.Sum();
        Console.WriteLine($"\nTotal inventory value: ${totalValue:F2}");

        // Average price
        double averagePrice = productPrices.Values.Average();
        Console.WriteLine($"Average price: ${averagePrice:F2}");

        // Find cheapest and most expensive
        var cheapest = productPrices.OrderBy(kvp => kvp.Value).First();
        var mostExpensive = productPrices.OrderByDescending(kvp => kvp.Value).First();

        Console.WriteLine($"Cheapest: {cheapest.Key} (${cheapest.Value:F2})");
        Console.WriteLine($"Most expensive: {mostExpensive.Key} (${mostExpensive.Value:F2})");
    }

    // 6. Dictionary with custom comparers
    public static void CustomDictionaryComparers()
    {
        Console.WriteLine("\n=== Custom Dictionary Comparers ===");

        // Case-insensitive string key dictionary
        Dictionary<string, int> caseInsensitiveDict = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
        caseInsensitiveDict.Add("Apple", 1);
        caseInsensitiveDict.Add("Banana", 2);

        Console.WriteLine("Case-insensitive dictionary:");
        PrintDictionary(caseInsensitiveDict);

        // These operations work regardless of case
        Console.WriteLine($"Contains 'apple': {caseInsensitiveDict.ContainsKey("apple")}");
        Console.WriteLine($"Contains 'APPLE': {caseInsensitiveDict.ContainsKey("APPLE")}");

        caseInsensitiveDict["APPLE"] = 3; // Updates the existing "Apple"
        Console.WriteLine($"After update, 'Apple' value: {caseInsensitiveDict["Apple"]}");

        // Sorted dictionary
        SortedDictionary<string, int> sortedDict = new SortedDictionary<string, int>
        {
            { "Zebra", 1 },
            { "Apple", 2 },
            { "Banana", 3 },
            { "Cherry", 4 }
        };

        Console.WriteLine("\nSorted dictionary (automatic alphabetical order):");
        PrintDictionary(sortedDict);
    }

    // 7. Concurrent dictionary for multi-threading
    public static void ConcurrentDictionaryDemo()
    {
        Console.WriteLine("\n=== Concurrent Dictionary ===");

        var concurrentDict = new System.Collections.Concurrent.ConcurrentDictionary<string, int>();

        // Try add operations
        bool added1 = concurrentDict.TryAdd("Thread1", 1);
        bool added2 = concurrentDict.TryAdd("Thread1", 2); // Won't add since key exists
        bool added3 = concurrentDict.TryAdd("Thread2", 2);

        Console.WriteLine($"Added Thread1 first time: {added1}");
        Console.WriteLine($"Added Thread1 second time: {added2}");
        Console.WriteLine($"Added Thread2: {added3}");

        // Try update
        bool updated = concurrentDict.TryUpdate("Thread1", 3, 1);
        Console.WriteLine($"Updated Thread1 from 1 to 3: {updated}");

        // Get or add
        int value = concurrentDict.GetOrAdd("Thread3", 3);
        Console.WriteLine($"GetOrAdd Thread3: {value}");

        // Add or update
        concurrentDict.AddOrUpdate("Thread2", 5, (key, existingValue) => existingValue * 2);

        Console.WriteLine("\nConcurrent dictionary contents:");
        PrintConcurrentDictionary(concurrentDict);
    }

    // 8. Dictionary performance considerations
    public static void DictionaryPerformance()
    {
        Console.WriteLine("\n=== Dictionary Performance ===");

        const int itemCount = 100000;
        var dictionary = new Dictionary<int, string>();
        var hashtable = new Hashtable();
        var random = new Random();

        // Populate collections
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Dictionary population
        stopwatch.Restart();
        for (int i = 0; i < itemCount; i++)
        {
            dictionary[i] = $"Item_{i}";
        }
        stopwatch.Stop();
        Console.WriteLine($"Dictionary population ({itemCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");

        // Hashtable population
        stopwatch.Restart();
        for (int i = 0; i < itemCount; i++)
        {
            hashtable[i] = $"Item_{i}";
        }
        stopwatch.Stop();
        Console.WriteLine($"Hashtable population ({itemCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");

        // Search performance
        int[] searchKeys = Enumerable.Range(0, 1000).Select(_ => random.Next(itemCount)).ToArray();

        stopwatch.Restart();
        foreach (int key in searchKeys)
        {
            dictionary.TryGetValue(key, out _);
        }
        stopwatch.Stop();
        Console.WriteLine($"Dictionary searches (1000 lookups): {stopwatch.ElapsedTicks} ticks");

        stopwatch.Restart();
        foreach (int key in searchKeys)
        {
            hashtable.ContainsKey(key);
        }
        stopwatch.Stop();
        Console.WriteLine($"Hashtable searches (1000 lookups): {stopwatch.ElapsedTicks} ticks");
    }

    // 9. Dictionary serialization and persistence
    public static void DictionaryPersistence()
    {
        Console.WriteLine("\n=== Dictionary Persistence ===");

        Dictionary<string, object> settings = new Dictionary<string, object>
        {
            { "AppName", "MyApplication" },
            { "Version", "1.0.0" },
            { "MaxUsers", 100 },
            { "EnableLogging", true },
            { "ApiKey", "abc123xyz" }
        };

        Console.WriteLine("Application settings:");
        PrintDictionary(settings);

        // Serialize to JSON (simplified)
        string json = System.Text.Json.JsonSerializer.Serialize(settings, new System.Text.Json.JsonSerializerOptions { WriteIndented = true });
        Console.WriteLine("\nJSON representation:");
        Console.WriteLine(json);

        // Save to file
        string filePath = "settings.json";
        System.IO.File.WriteAllText(filePath, json);
        Console.WriteLine($"
Settings saved to {filePath}");

        // Load from file
        if (System.IO.File.Exists(filePath))
        {
            string loadedJson = System.IO.File.ReadAllText(filePath);
            var loadedSettings = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(loadedJson);

            Console.WriteLine("
Loaded settings:");
            if (loadedSettings != null)
            {
                PrintDictionary(loadedSettings.ToDictionary(kvp => kvp.Key, kvp => kvp.Value));
            }

            // Cleanup
            System.IO.File.Delete(filePath);
        }
    }

    // 10. Advanced dictionary patterns
    public static void AdvancedDictionaryPatterns()
    {
        Console.WriteLine("\n=== Advanced Dictionary Patterns ===");

        // Lookup dictionary (for multiple values per key)
        Dictionary<string, List<int>> multiValues = new Dictionary<string, List<int>>
        {
            { "Even", new List<int>() },
            { "Odd", new List<int>() }
        };

        // Group numbers by parity
        for (int i = 1; i <= 10; i++)
        {
            string key = i % 2 == 0 ? "Even" : "Odd";
            multiValues[key].Add(i);
        }

        Console.WriteLine("Numbers grouped by parity:");
        foreach (var group in multiValues)
        {
            Console.WriteLine($"{group.Key}: [{string.Join(", ", group.Value)}]");
        }

        // Nested dictionary
        Dictionary<string, Dictionary<string, int>> nestedDict = new Dictionary<string, Dictionary<string, int>>
        {
            { "Products", new Dictionary<string, int>
                {
                    { "Electronics", 150 },
                    { "Clothing", 80 },
                    { "Books", 200 }
                }
            },
            { "Services", new Dictionary<string, int>
                {
                    { "Consulting", 50 },
                    { "Support", 120 },
                    { "Training", 30 }
                }
            }
        };

        Console.WriteLine("\nNested dictionary:");
        foreach (var category in nestedDict)
        {
            Console.WriteLine($"{category.Key}:");
            foreach (var item in category.Value)
            {
                Console.WriteLine($"  {item.Item1}: {item.Item2}");
            }
        }

        // Default dictionary pattern
        Dictionary<string, int> wordCounts = new Dictionary<string, int>();
        string text = "the quick brown fox jumps over the lazy dog the quick brown fox";
        string[] words = text.Split();

        foreach (string word in words)
        {
            if (wordCounts.ContainsKey(word))
            {
                wordCounts[word]++;
            }
            else
            {
                wordCounts[word] = 1;
            }
        }

        Console.WriteLine("\nWord frequency count:");
        foreach (var wordCount in wordCounts.OrderByDescending(kvp => kvp.Value))
        {
            Console.WriteLine($"{wordCount.Key}: {wordCount.Value}");
        }
    }

    // Helper classes
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public override bool Equals(object obj)
        {
            if (obj is Person other)
            {
                return Id == other.Id && Name == other.Name;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return HashCode.Combine(Id, Name);
        }
    }

    // Helper methods
    static void PrintDictionary<T, U>(Dictionary<T, U> dict)
    {
        foreach (var kvp in dict)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }

    static void PrintDictionary(Dictionary<string, object> dict)
    {
        foreach (var kvp in dict)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value} ({kvp.Value.GetType().Name})");
        }
    }

    static void PrintNestedDictionary(Dictionary<string, List<string>> dict)
    {
        foreach (var kvp in dict)
        {
            Console.WriteLine($"{kvp.Key}: [{string.Join(", ", kvp.Value)}]");
        }
    }

    static void PrintConcurrentDictionary(System.Collections.Concurrent.ConcurrentDictionary<string, int> dict)
    {
        foreach (var kvp in dict)
        {
            Console.WriteLine($"{kvp.Key}: {kvp.Value}");
        }
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# Hashtable and Dictionary Demo ===\n");

        try
        {
            DictionaryBasics();
            DictionaryWithDifferentTypes();
            HashtableBasics();
            DictionaryOperations();
            DictionarySearching();
            CustomDictionaryComparers();
            ConcurrentDictionaryDemo();
            DictionaryPerformance();
            DictionaryPersistence();
            AdvancedDictionaryPatterns();

            Console.WriteLine("\nAll hashtable and dictionary examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in hashtable demo: {ex.Message}");
        }
    }
}

💻 链表操作 csharp

🟡 intermediate ⭐⭐⭐

C#中单向和双向链表实现、操作和使用模式

⏱️ 30 min 🏷️ csharp, linked list, data structures, custom implementations, windows
Prerequisites: C# classes, Generics, Reference types
using System;
using System.Collections.Generic;

class LinkedListOperations
{
    // 1. Singly linked list implementation
    public class SinglyLinkedList<T>
    {
        private class Node
        {
            public T Data { get; set; }
            public Node Next { get; set; }

            public Node(T data)
            {
                Data = data;
                Next = null;
            }
        }

        private Node head;
        private int count;

        public int Count => count;
        public bool IsEmpty => head == null;

        public void AddFirst(T data)
        {
            Node newNode = new Node(data);
            newNode.Next = head;
            head = newNode;
            count++;
        }

        public void AddLast(T data)
        {
            Node newNode = new Node(data);

            if (head == null)
            {
                head = newNode;
            }
            else
            {
                Node current = head;
                while (current.Next != null)
                {
                    current = current.Next;
                }
                current.Next = newNode;
            }
            count++;
        }

        public bool Remove(T data)
        {
            if (head == null) return false;

            if (head.Data.Equals(data))
            {
                head = head.Next;
                count--;
                return true;
            }

            Node current = head;
            while (current.Next != null)
            {
                if (current.Next.Data.Equals(data))
                {
                    current.Next = current.Next.Next;
                    count--;
                    return true;
                }
                current = current.Next;
            }

            return false;
        }

        public bool Contains(T data)
        {
            Node current = head;
            while (current != null)
            {
                if (current.Data.Equals(data))
                    return true;
                current = current.Next;
            }
            return false;
        }

        public void Clear()
        {
            head = null;
            count = 0;
        }

        public void Print()
        {
            Node current = head;
            Console.Write("Head -> ");
            while (current != null)
            {
                Console.Write($"{current.Data} -> ");
                current = current.Next;
            }
            Console.WriteLine("Null");
        }

        public IEnumerator<T> GetEnumerator()
        {
            Node current = head;
            while (current != null)
            {
                yield return current.Data;
                current = current.Next;
            }
        }
    }

    // 2. Doubly linked list implementation
    public class DoublyLinkedList<T>
    {
        private class Node
        {
            public T Data { get; set; }
            public Node Previous { get; set; }
            public Node Next { get; set; }

            public Node(T data)
            {
                Data = data;
                Previous = null;
                Next = null;
            }
        }

        private Node head;
        private Node tail;
        private int count;

        public int Count => count;
        public bool IsEmpty => head == null;

        public void AddFirst(T data)
        {
            Node newNode = new Node(data);
            if (head == null)
            {
                head = tail = newNode;
            }
            else
            {
                newNode.Next = head;
                head.Previous = newNode;
                head = newNode;
            }
            count++;
        }

        public void AddLast(T data)
        {
            Node newNode = new Node(data);
            if (tail == null)
            {
                head = tail = newNode;
            }
            else
            {
                tail.Next = newNode;
                newNode.Previous = tail;
                tail = newNode;
            }
            count++;
        }

        public bool Remove(T data)
        {
            Node current = head;
            while (current != null)
            {
                if (current.Data.Equals(data))
                {
                    if (current.Previous != null)
                        current.Previous.Next = current.Next;
                    else
                        head = current.Next;

                    if (current.Next != null)
                        current.Next.Previous = current.Previous;
                    else
                        tail = current.Previous;

                    count--;
                    return true;
                }
                current = current.Next;
            }
            return false;
        }

        public void PrintForward()
        {
            Node current = head;
            Console.Write("Head -> ");
            while (current != null)
            {
                Console.Write($"{current.Data} <-> ");
                current = current.Next;
            }
            Console.WriteLine("Null");
        }

        public void PrintBackward()
        {
            Node current = tail;
            Console.Write("Tail -> ");
            while (current != null)
            {
                Console.Write($"{current.Data} <-> ");
                current = current.Previous;
            }
            Console.WriteLine("Null");
        }
    }

    // 3. Singly linked list operations
    public static void SinglyLinkedListOperations()
    {
        Console.WriteLine("=== Singly Linked List Operations ===");

        SinglyLinkedList<int> list = new SinglyLinkedList<int>();

        Console.WriteLine("Adding elements to linked list:");
        list.AddFirst(10);
        Console.WriteLine("Added 10 to front:");
        list.Print();

        list.AddLast(20);
        Console.WriteLine("Added 20 to back:");
        list.Print();

        list.AddFirst(5);
        Console.WriteLine("Added 5 to front:");
        list.Print();

        list.AddLast(30);
        Console.WriteLine("Added 30 to back:");
        list.Print();

        Console.WriteLine($"\nList count: {list.Count}");
        Console.WriteLine($"List is empty: {list.IsEmpty}");

        Console.WriteLine("\nSearching for elements:");
        Console.WriteLine($"Contains 20: {list.Contains(20)}");
        Console.WriteLine($"Contains 99: {list.Contains(99)}");

        Console.WriteLine("\nRemoving elements:");
        bool removed = list.Remove(20);
        Console.WriteLine($"Removed 20: {removed}");
        list.Print();

        removed = list.Remove(99);
        Console.WriteLine($"Removed 99: {removed}");
        list.Print();

        // Iterate through the list
        Console.WriteLine("\nIterating through the list:");
        foreach (int item in list)
        {
            Console.WriteLine($"Item: {item}");
        }
    }

    // 4. Doubly linked list operations
    public static void DoublyLinkedListOperations()
    {
        Console.WriteLine("\n=== Doubly Linked List Operations ===");

        DoublyLinkedList<string> list = new DoublyLinkedList<string>();

        Console.WriteLine("Adding elements to doubly linked list:");
        list.AddFirst("B");
        Console.WriteLine("Added 'B' to front:");
        list.PrintForward();

        list.AddLast("C");
        Console.WriteLine("Added 'C' to back:");
        list.PrintForward();

        list.AddFirst("A");
        Console.WriteLine("Added 'A' to front:");
        list.PrintForward();

        list.AddLast("D");
        Console.WriteLine("Added 'D' to back:");
        list.PrintForward();

        Console.WriteLine("\nForward traversal:");
        list.PrintForward();

        Console.WriteLine("\nBackward traversal:");
        list.PrintBackward();

        Console.WriteLine($"\nList count: {list.Count}");

        Console.WriteLine("\nRemoving 'B':");
        list.Remove("B");
        list.PrintForward();

        Console.WriteLine("\nBackward traversal after removal:");
        list.PrintBackward();
    }

    // 5. Built-in LinkedList<T> operations
    public static void BuiltInLinkedListOperations()
    {
        Console.WriteLine("\n=== Built-in LinkedList<T> Operations ===");

        LinkedList<string> list = new LinkedList<string>();

        Console.WriteLine("Adding elements to built-in LinkedList:");
        list.AddFirst("Second");
        Console.WriteLine("Added 'Second' to first position:");

        list.AddFirst("First");
        Console.WriteLine("Added 'First' to first position:");

        list.AddLast("Third");
        Console.WriteLine("Added 'Third' to last position:");

        list.AddLast("Fourth");
        Console.WriteLine("Added 'Fourth' to last position:");

        Console.WriteLine("\nLinkedList contents:");
        foreach (string item in list)
        {
            Console.WriteLine(item);
        }

        // Get references to nodes
        LinkedListNode<string> firstNode = list.First;
        LinkedListNode<string> lastNode = list.Last;

        Console.WriteLine($$"\nFirst node: {firstNode?.Value}");
        Console.WriteLine($"Last node: {lastNode?.Value}");

        // Insert after and before specific nodes
        LinkedListNode<string> secondNode = firstNode.Next;
        list.AddAfter(secondNode, "Second and a Half");
        Console.WriteLine("\nAfter adding 'Second and a Half' after 'Second':");
        foreach (string item in list)
        {
            Console.WriteLine(item);
        }

        list.AddBefore(lastNode, "Third and a Half");
        Console.WriteLine("\nAfter adding 'Third and a Half' before 'Fourth':");
        foreach (string item in list)
        {
            Console.WriteLine(item);
        }

        // Remove specific values
        list.Remove("Second and a Half");
        Console.WriteLine("\nAfter removing 'Second and a Half':");
        foreach (string item in list)
        {
            Console.WriteLine(item);
        }

        // Remove first and last
        list.RemoveFirst();
        list.RemoveLast();
        Console.WriteLine("\nAfter removing first and last:");
        foreach (string item in list)
        {
            Console.WriteLine(item);
        }

        Console.WriteLine($"\nLinkedList count: {list.Count}");
    }

    // 6. LinkedList performance comparison
    public static void LinkedListPerformanceComparison()
    {
        Console.WriteLine("\n=== LinkedList Performance Comparison ===");

        const int itemCount = 10000;
        var random = new Random();

        // Test built-in LinkedList
        var linkedList = new LinkedList<int>();
        var stopwatch = System.Diagnostics.Stopwatch.StartNew();

        // Adding elements
        stopwatch.Restart();
        for (int i = 0; i < itemCount; i++)
        {
            linkedList.AddLast(i);
        }
        stopwatch.Stop();
        Console.WriteLine($"LinkedList.AddLast ({itemCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");

        // Test List<T>
        var list = new List<int>();
        stopwatch.Restart();
        for (int i = 0; i < itemCount; i++)
        {
            list.Add(i);
        }
        stopwatch.Stop();
        Console.WriteLine($"List.Add ({itemCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");

        // Test insertion at beginning
        int insertCount = 1000;
        stopwatch.Restart();
        for (int i = 0; i < insertCount; i++)
        {
            linkedList.AddFirst(i);
        }
        stopwatch.Stop();
        Console.WriteLine($"LinkedList.AddFirst ({insertCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");

        stopwatch.Restart();
        for (int i = 0; i < insertCount; i++)
        {
            list.Insert(0, i);
        }
        stopwatch.Stop();
        Console.WriteLine($"List.Insert(0) ({insertCount:N0} items): {stopwatch.ElapsedMilliseconds}ms");
    }

    // 7. LinkedList use cases
    public static void LinkedListUseCases()
    {
        Console.WriteLine("\n=== LinkedList Use Cases ===");

        // Use case 1: Undo/Redo functionality
        Console.WriteLine("Use Case 1: Undo/Redo System");
        UndoRedoSystem undoRedo = new UndoRedoSystem();

        undoRedo.PerformAction("Type text");
        undoRedo.PerformAction("Delete character");
        undoRedo.PerformAction("Format text");

        Console.WriteLine($"Current action: {undoRedo.GetCurrentAction()}");
        Console.WriteLine($"Undo: {undoRedo.Undo()}");
        Console.WriteLine($"Current action: {undoRedo.GetCurrentAction()}");
        Console.WriteLine($"Redo: {undoRedo.Redo()}");
        Console.WriteLine($"Current action: {undoRedo.GetCurrentAction()}");

        // Use case 2: Music playlist
        Console.WriteLine("\nUse Case 2: Music Playlist");
        MusicPlaylist playlist = new MusicPlaylist();

        playlist.AddSong("Song 1 - Artist A");
        playlist.AddSong("Song 2 - Artist B");
        playlist.AddSong("Song 3 - Artist C");

        Console.WriteLine("Current playlist:");
        playlist.PrintPlaylist();

        Console.WriteLine($"\nPlaying: {playlist.PlayNext()}");
        Console.WriteLine($"Playing: {playlist.PlayNext()}");
        Console.WriteLine($"Playing: {playlist.PlayNext()}");
        Console.WriteLine($"Playing: {playlist.PlayNext()}"); // Should wrap around

        // Use case 3: Browser history
        Console.WriteLine("\nUse Case 3: Browser History");
        BrowserHistory history = new BrowserHistory();

        history.VisitPage("https://google.com");
        history.VisitPage("https://stackoverflow.com");
        history.VisitPage("https://github.com");

        Console.WriteLine("Current page: " + history.GetCurrentPage());
        Console.WriteLine("Go back: " + history.GoBack());
        Console.WriteLine("Go back: " + history.GoBack());
        Console.WriteLine("Go forward: " + history.GoForward());
    }

    // Helper classes for use cases
    public class UndoRedoSystem
    {
        private LinkedList<string> actions = new LinkedList<string>();
        private LinkedListNode<string> currentAction;

        public void PerformAction(string action)
        {
            // Remove all actions after current position
            while (currentAction?.Next != null)
            {
                actions.RemoveLast();
            }

            actions.AddLast(action);
            currentAction = actions.Last;
        }

        public string Undo()
        {
            if (currentAction?.Previous != null)
            {
                currentAction = currentAction.Previous;
                return currentAction.Value;
            }
            return "Nothing to undo";
        }

        public string Redo()
        {
            if (currentAction?.Next != null)
            {
                currentAction = currentAction.Next;
                return currentAction.Value;
            }
            return "Nothing to redo";
        }

        public string GetCurrentAction()
        {
            return currentAction?.Value ?? "No actions";
        }
    }

    public class MusicPlaylist
    {
        private LinkedList<string> songs = new LinkedList<string>();
        private LinkedListNode<string> currentSong;

        public void AddSong(string song)
        {
            if (songs.Count == 0)
            {
                songs.AddFirst(song);
                currentSong = songs.First;
            }
            else
            {
                songs.AddLast(song);
            }
        }

        public string PlayNext()
        {
            if (currentSong?.Next != null)
            {
                currentSong = currentSong.Next;
            }
            else
            {
                currentSong = songs.First; // Wrap around
            }
            return currentSong?.Value ?? "No songs";
        }

        public string PlayPrevious()
        {
            if (currentSong?.Previous != null)
            {
                currentSong = currentSong.Previous;
            }
            else
            {
                currentSong = songs.Last; // Wrap around
            }
            return currentSong?.Value ?? "No songs";
        }

        public void PrintPlaylist()
        {
            foreach (string song in songs)
            {
                string marker = song == currentSong?.Value ? " (Current)" : "";
                Console.WriteLine(song + marker);
            }
        }
    }

    public class BrowserHistory
    {
        private LinkedList<string> pages = new LinkedList<string>();
        private LinkedListNode<string> currentPage;

        public void VisitPage(string url)
        {
            if (currentPage?.Next != null)
            {
                // Clear forward history
                var node = currentPage.Next;
                while (node != null)
                {
                    var next = node.Next;
                    pages.Remove(node);
                    node = next;
                }
            }

            pages.AddLast(url);
            currentPage = pages.Last;
        }

        public string GoBack()
        {
            if (currentPage?.Previous != null)
            {
                currentPage = currentPage.Previous;
                return currentPage.Value;
            }
            return "No previous page";
        }

        public string GoForward()
        {
            if (currentPage?.Next != null)
            {
                currentPage = currentPage.Next;
                return currentPage.Value;
            }
            return "No next page";
        }

        public string GetCurrentPage()
        {
            return currentPage?.Value ?? "No pages";
        }
    }

    // 8. Circular linked list
    public class CircularLinkedList<T>
    {
        private class Node
        {
            public T Data { get; set; }
            public Node Next { get; set; }

            public Node(T data)
            {
                Data = data;
                Next = null;
            }
        }

        private Node head;
        private int count;

        public int Count => count;
        public bool IsEmpty => head == null;

        public void Add(T data)
        {
            Node newNode = new Node(data);

            if (head == null)
            {
                head = newNode;
                head.Next = head; // Points to itself
            }
            else
            {
                Node current = head;
                while (current.Next != head)
                {
                    current = current.Next;
                }
                current.Next = newNode;
                newNode.Next = head;
            }
            count++;
        }

        public void Print()
        {
            if (head == null)
            {
                Console.WriteLine("Empty circular list");
                return;
            }

            Node current = head;
            Console.Write("Head -> ");
            do
            {
                Console.Write($"{current.Data} -> ");
                current = current.Next;
            } while (current != head);
            Console.WriteLine("(back to Head)");
        }

        public void Rotate(int positions)
        {
            if (head == null || count <= 1) return;

            for (int i = 0; i < Math.Abs(positions) % count; i++)
            {
                if (positions > 0)
                {
                    head = head.Next;
                }
                else
                {
                    // Find previous node
                    Node current = head;
                    while (current.Next != head)
                    {
                        current = current.Next;
                    }
                    head = current;
                }
            }
        }
    }

    public static void CircularLinkedListDemo()
    {
        Console.WriteLine("\n=== Circular Linked List Demo ===");

        CircularLinkedList<char> circle = new CircularLinkedList<char>();

        circle.Add('A');
        circle.Add('B');
        circle.Add('C');
        circle.Add('D');

        Console.WriteLine("Initial circular list:");
        circle.Print();

        Console.WriteLine("\nRotate right by 1 position:");
        circle.Rotate(1);
        circle.Print();

        Console.WriteLine("\nRotate right by 2 positions:");
        circle.Rotate(2);
        circle.Print();

        Console.WriteLine("\nRotate left by 1 position:");
        circle.Rotate(-1);
        circle.Print();
    }

    static void Main(string[] args)
    {
        Console.WriteLine("=== C# Linked List Operations Demo ===\n");

        try
        {
            SinglyLinkedListOperations();
            DoublyLinkedListOperations();
            BuiltInLinkedListOperations();
            LinkedListPerformanceComparison();
            LinkedListUseCases();
            CircularLinkedListDemo();

            Console.WriteLine("\nAll linked list examples completed successfully!");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error in linked list demo: {ex.Message}");
        }
    }
}