Created
March 14, 2017 20:12
-
-
Save jianminchen/89c782da398dbbf1865366e55eaf39ec to your computer and use it in GitHub Desktop.
Quicksort - practice after the code review - review and make code more readable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Diagnostics; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
namespace quickSortAlgorithm_B | |
{ | |
/// <summary> | |
/// Quick sort - choose pivot point as the last element in the array, and use in-place algorithm. No extra space. | |
/// | |
/// </summary> | |
class Solution | |
{ | |
static void Main(string[] args) | |
{ | |
RunTestcase_Partition(); | |
RunTestcase_QuickSort(); | |
} | |
public static void RunTestcase_QuickSort() | |
{ | |
int[] numbers = { 1, 6, 2, 5, 4, 3 }; | |
Quicksort(numbers, 0, 5); | |
Debug.Assert(String.Join(" ",numbers).ToString().CompareTo("1 2 3 4 5 6") == 0); | |
} | |
/// <summary> | |
/// 1. verify the partition function return value - pivot point position - index of the array | |
/// 2. verify the numbers's array with correct order of numbers | |
/// </summary> | |
public static void RunTestcase_Partition() | |
{ | |
int[] numbers = { 1, 6, 2, 5, 4, 3 }; | |
int position = partition(numbers, 0, 5); | |
Debug.Assert(position == 2); | |
Debug.Assert(String.Join(" ", numbers).ToString().CompareTo("1 2 3 5 4 6") == 0); | |
} | |
/// <summary> | |
/// March 14, 2017 | |
/// How to design this recurisve fucntion? | |
/// Sort array using quick sort | |
/// Design tips and discussion: | |
/// 1. First, remember using recursive function, divide and conquer | |
/// 2. One array - for all the recursive function | |
/// But each recursive will work on part of the array - left / right position | |
/// 3. Remember how to do 2-way partition - how to choose pivot - how to use pivot point value to divide | |
/// into 2 partitions - left side - smaller values, right side - bigger values | |
/// 4. Partition - | |
/// two pointers - one pointer is to iterate whole array, except pivot point | |
/// second pointer - position of first node bigger than pivot value | |
/// | |
/// Actually, after the practice of February 2, 2016, Julia found out that two pointers can be designed | |
/// much easy way: | |
/// 1. First pointer - look for second partition part - right partition - start position | |
/// 2. Second pointer - look for second partition part - right partition - end position | |
/// and also, in partition process, in-place swap is used. | |
/// | |
/// Do not forget to swap second pointer value with pivot point value | |
/// 5. Practice to write code using array - how to write code without a bug? | |
/// 6. the output is stored in the input argument A[] | |
/// </summary> | |
/// <param name="numbers"></param> | |
/// <param name="left"></param> | |
/// <param name="right"></param> | |
public static void Quicksort(int[] numbers, int left, int right) | |
{ | |
if (left > right || left < 0 || right < 0) return; | |
int index = partition(numbers, left, right); | |
if (index != -1) | |
{ | |
Quicksort(numbers, left, index - 1); | |
Quicksort(numbers, index + 1, right); | |
} | |
} | |
/// <summary> | |
/// March 14, 2017 | |
/// Partition tips for design: | |
/// Use array int[] numbers to store the values | |
/// 2. choose pivot point smartly - use last value in the array here | |
/// 3. actually partition is to find two pointers of right partition, start and end position. | |
/// start position's pointer will iterate the array from start | |
/// 4. At last, put pivot point value between two partition, one swap | |
/// | |
/// Test case: | |
/// int[] numbers = { 1, 6, 2, 5, 4, 3 }; | |
/// Two swaps for test case: | |
/// 1. one swap for partition for pivot point 3, one swap for put pivot value in-between | |
/// 6 and 2 swap | |
/// 6 and 3 swap | |
/// 2. left partition 2 values, right partition 3 values. | |
/// | |
/// variable startRihtPartition -> 0 -> 1 -> 2 | |
/// </summary> | |
/// <param name="numbers"> array of numbers to be partitioned</param> | |
/// <param name="left">start position of the array</param> | |
/// <param name="right">end position of the array</param> | |
/// <returns></returns> | |
private static int partition(int[] numbers, int left, int right) | |
{ | |
if (left > right) | |
{ | |
return -1; | |
} | |
// right partition - 2nd one's start position; 2nd one's end position will be right-1 | |
int startRightPartition = left; | |
// choose last one to pivot, easy to code | |
int pivot = numbers[right]; | |
for (int i = left; i < right; i++) | |
{ | |
if (numbers[i] < pivot) | |
{ | |
swap(numbers, i, startRightPartition); | |
startRightPartition++; | |
} | |
} | |
// insert pivot point in two sections | |
swap(numbers, startRightPartition, right); | |
return startRightPartition; | |
} | |
private static void swap(int[] array, int left, int right) | |
{ | |
int tmp = array[left]; | |
array[left] = array[right]; | |
array[right] = tmp; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment