C#面向对象作业:为插入排序、计数排序类实现排序统计功能
Great question! Since you're already using inheritance with a base Sort class, we can lean into OOP principles like encapsulation and code reuse to add the required statistics tracking cleanly. Here's how to do it step by step:
Step 1: Refactor the Base Sort Class
First, we'll add read-only properties for all the required statistics to the base class, along with a template method that handles tracking time and calculating metrics. This way, both child classes inherit this functionality without repeating code.
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; public abstract class Sort { // Read-only statistics properties public int ElementCount { get; private set; } public TimeSpan SortingTime { get; private set; } public int MinValue { get; private set; } public int MaxValue { get; private set; } public double AverageValue { get; private set; } // Template method: handles stats tracking and delegates sorting to child classes public List<int> SortAndTrackStats(List<int> inputList) { // Validate input (avoid nulls/empty lists) if (inputList == null || inputList.Count == 0) throw new ArgumentException("Input list cannot be null or empty."); // Initialize pre-sort stats ElementCount = inputList.Count; MinValue = inputList.Min(); MaxValue = inputList.Max(); AverageValue = inputList.Average(); // Create a copy to avoid modifying the original list (optional but good practice) List<int> sortedList = new List<int>(inputList); // Track sorting time Stopwatch stopwatch = Stopwatch.StartNew(); // Call the child class's specific sorting logic PerformSort(sortedList); stopwatch.Stop(); SortingTime = stopwatch.Elapsed; return sortedList; } // Abstract method: child classes implement their sorting logic here protected abstract void PerformSort(List<int> sortList); }
Step 2: Update Your Sorting Classes
Modify InsertionSorting and CountSorting to implement the PerformSort abstract method instead of your original Sorting method. This keeps the focus on the sorting algorithm itself, while the base class handles all stats work.
Insertion Sort Class
public class InsertionSorting : Sort { protected override void PerformSort(List<int> sortList) { for (int i = 0; i < sortList.Count - 1; i++) { for (int j = i + 1; j > 0; j--) { if (sortList[j - 1] > sortList[j]) { int temp = sortList[j - 1]; sortList[j - 1] = sortList[j]; sortList[j] = temp; } } } } }
Count Sort Class
Note: Your original count sort assumes values are between 0 and 999. We'll keep that logic but adjust it to work with the PerformSort method:
public class CountSorting : Sort { protected override void PerformSort(List<int> sortList) { int n = sortList.Count; List<int> output = new List<int>(new int[n]); List<int> count = new List<int>(new int[1000]); // Count occurrences for (int i = 0; i < n; ++i) ++count[sortList[i]]; // Compute cumulative counts for (int i = 1; i <= 999; ++i) count[i] += count[i - 1]; // Build output array (processing from end preserves stability) for (int i = n - 1; i >= 0; i--) { output[count[sortList[i]] - 1] = sortList[i]; --count[sortList[i]]; } // Copy sorted values back to original list for (int i = 0; i < n; i++) sortList[i] = output[i]; } }
Step 3: Use the Classes and Access Statistics
Here's how you can test this with random numbers and view the stats:
class Program { static void Main() { // Generate a list of 1000 random integers between 0 and 999 Random random = new Random(); List<int> randomNumbers = Enumerable.Range(0, 1000) .Select(_ => random.Next(0, 1000)) .ToList(); // Test Insertion Sort Console.WriteLine("=== Insertion Sort Stats ==="); InsertionSorting insertionSort = new InsertionSorting(); List<int> sortedInsertion = insertionSort.SortAndTrackStats(randomNumbers); Console.WriteLine($"Element Count: {insertionSort.ElementCount}"); Console.WriteLine($"Sorting Time: {insertionSort.SortingTime.TotalMilliseconds:F2} ms"); Console.WriteLine($"Min Value: {insertionSort.MinValue}"); Console.WriteLine($"Max Value: {insertionSort.MaxValue}"); Console.WriteLine($"Average Value: {insertionSort.AverageValue:F2}\n"); // Test Count Sort (use a fresh copy of random numbers) Console.WriteLine("=== Count Sort Stats ==="); CountSorting countSort = new CountSorting(); List<int> sortedCount = countSort.SortAndTrackStats(new List<int>(randomNumbers)); Console.WriteLine($"Element Count: {countSort.ElementCount}"); Console.WriteLine($"Sorting Time: {countSort.SortingTime.TotalMilliseconds:F2} ms"); Console.WriteLine($"Min Value: {countSort.MinValue}"); Console.WriteLine($"Max Value: {countSort.MaxValue}"); Console.WriteLine($"Average Value: {countSort.AverageValue:F2}"); } }
Key OOP Principles Followed
- Encapsulation: Statistics are stored as private fields with public read-only properties, preventing external modification and ensuring data integrity.
- Inheritance: Both sorting classes inherit the stats tracking logic from the base
Sortclass, eliminating code duplication. - Single Responsibility: Each sorting class only focuses on implementing its algorithm, while the base class handles statistics and timing.
- Template Method Pattern: The
SortAndTrackStatsmethod defines the skeleton of the sorting process, delegating the actual sorting to child classes.
内容的提问来源于stack exchange,提问作者muhammed kocoglu

