Implement quicksort and a binary search tree, and explain how each works internally

Quick Overview

Implement quicksort and a binary search tree from scratch and explain how each works internally, including partitioning, pivot choice, insertion, search and deletion. Tests correctness invariants, best, average and worst-case complexity, duplicate and sorted inputs, alternative approaches, and how library implementations differ.

Implement quicksort and a binary search tree, and explain how each works internally

Company: Google

Role: Software Engineer

Category: Software Engineering Fundamentals

Difficulty: medium

Interview Round: Technical Screen

During an algorithm-focused technical round, the interviewer went beyond the coding problem and asked how the algorithms and data structures used in the solution work underneath, for example how quicksort is implemented and how a binary search tree is implemented. The round expected more than one approach, precise answers about implementation details, and readable code. Implement both from scratch, without library sorting or tree types, and explain each one. ### Clarifying Questions - Should quicksort sort in place, or may it return a new list? Does it need to be stable? - Can the input contain many duplicates, or arrive already sorted or reverse sorted? - Which tree operations are required: insert, search and delete only, or also in-order traversal, minimum, maximum and size? - Are duplicate keys allowed in the tree, and if so, where do they go? - Is a plain binary search tree enough, with its worst case explained, or must the tree stay balanced? ### Part 1 — Quicksort Implement quicksort for a list of integers. Explain how partitioning works and why the algorithm is correct; give its best, average and worst-case running time and its extra space; explain how the choice of pivot affects them; and describe an alternative partition scheme and when it behaves differently. ```hint What partition promises State exactly what is true of the subarray after one partition step, and check that every iteration of your loop keeps that statement true, including when an element equals the pivot. ``` ```hint Where the worst case comes from Run your implementation by hand on an already sorted array and on an array of identical values, and watch how the subarray sizes shrink. ``` #### What This Part Should Cover - A correct partition with its invariant, and the recursion around it - Best, average and worst-case time, and the recursion depth with a way to bound it - Pivot selection, duplicate handling, and a comparison of partition schemes - Stability and in-place behavior ### Part 2 — Binary search tree Implement a binary search tree of integer keys with insert, search and delete, plus an in-order traversal. Explain the ordering invariant, the cost of each operation, what happens to that cost when keys are inserted in sorted order, and the ways to delete a node that has two children. ```hint The hard case of delete Removing a node with no children or one child is a local change. For a node with two children, ask which other key could take its place without breaking the ordering, and where that key lives. ``` #### What This Part Should Cover - The node structure, the ordering invariant and a duplicate-key policy - Insert, search and delete, including the two-children case and deleting the root - Cost in terms of tree height, the degenerate case, and how self-balancing trees bound the height - A clean class interface that separates public operations from private helpers ### What a Strong Answer Covers - Working, readable code for both structures, written without library helpers - Invariants stated precisely enough to justify correctness - Complexity with best, average and worst cases distinguished, including the space used by recursion - More than one approach for each, with the conditions under which each one is better - Edge cases: empty input, a single element, duplicates, sorted input, deleting the root, deleting a missing key - Awareness of how library sorts and ordered containers differ from the textbook versions, and why ### Follow-up Questions - Your language's built-in sort is not plain quicksort. What does it typically use, and why? - How can quicksort's worst case be made O(n log n) without giving up sorting in place? - How would you find the k-th smallest element of an unsorted array using the partition step, and what does it cost? - Standard-library ordered maps are usually red-black trees rather than plain binary search trees. What does that buy, and what does a red-black tree add to each node?

Overview: Implement quicksort and a binary search tree from scratch and explain how each works internally, including partitioning, pivot choice, insertion, search and deletion. Tests correctness invariants, best, average and worst-case complexity, duplicate and sorted inputs, alternative approaches, and how library implementations differ.

Google logo
Google
Oct 5, 2026
mediumSoftware EngineerTechnical ScreenSoftware Engineering Fundamentals
0
0

During an algorithm-focused technical round, the interviewer went beyond the coding problem and asked how the algorithms and data structures used in the solution work underneath, for example how quicksort is implemented and how a binary search tree is implemented. The round expected more than one approach, precise answers about implementation details, and readable code. Implement both from scratch, without library sorting or tree types, and explain each one.

Clarifying Questions Guidance

  • Should quicksort sort in place, or may it return a new list? Does it need to be stable?
  • Can the input contain many duplicates, or arrive already sorted or reverse sorted?
  • Which tree operations are required: insert, search and delete only, or also in-order traversal, minimum, maximum and size?
  • Are duplicate keys allowed in the tree, and if so, where do they go?
  • Is a plain binary search tree enough, with its worst case explained, or must the tree stay balanced?

Part 1 — Quicksort

Implement quicksort for a list of integers. Explain how partitioning works and why the algorithm is correct; give its best, average and worst-case running time and its extra space; explain how the choice of pivot affects them; and describe an alternative partition scheme and when it behaves differently.

What This Part Should Cover Guidance

  • A correct partition with its invariant, and the recursion around it
  • Best, average and worst-case time, and the recursion depth with a way to bound it
  • Pivot selection, duplicate handling, and a comparison of partition schemes
  • Stability and in-place behavior

Part 2 — Binary search tree

Implement a binary search tree of integer keys with insert, search and delete, plus an in-order traversal. Explain the ordering invariant, the cost of each operation, what happens to that cost when keys are inserted in sorted order, and the ways to delete a node that has two children.

What This Part Should Cover Guidance

  • The node structure, the ordering invariant and a duplicate-key policy
  • Insert, search and delete, including the two-children case and deleting the root
  • Cost in terms of tree height, the degenerate case, and how self-balancing trees bound the height
  • A clean class interface that separates public operations from private helpers

What a Strong Answer Covers Guidance

  • Working, readable code for both structures, written without library helpers
  • Invariants stated precisely enough to justify correctness
  • Complexity with best, average and worst cases distinguished, including the space used by recursion
  • More than one approach for each, with the conditions under which each one is better
  • Edge cases: empty input, a single element, duplicates, sorted input, deleting the root, deleting a missing key
  • Awareness of how library sorts and ordered containers differ from the textbook versions, and why

Follow-up Questions Guidance

  • Your language's built-in sort is not plain quicksort. What does it typically use, and why?
  • How can quicksort's worst case be made O(n log n) without giving up sorting in place?
  • How would you find the k-th smallest element of an unsorted array using the partition step, and what does it cost?
  • Standard-library ordered maps are usually red-black trees rather than plain binary search trees. What does that buy, and what does a red-black tree add to each node?