Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@jianminchen
Created March 14, 2017 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jianminchen/89c782da398dbbf1865366e55eaf39ec to your computer and use it in GitHub Desktop.
Save jianminchen/89c782da398dbbf1865366e55eaf39ec to your computer and use it in GitHub Desktop.
Quicksort - practice after the code review - review and make code more readable
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