## A.6 Sets
Informally, a ***set*** is a collection of objects. We denote sets by capital letters such as *S*, and, if we enumerate all the objects in a set, we enclose them in braces. For example,
![](https://box.kancloud.cn/8dab4e3fc152d66a00c8e70c3c4cf78e_116x22.jpg)
is the set containing the first four positive integers. The order in which we list the objects is irrelevant. This means that
![](https://box.kancloud.cn/f6ffa238657dd51785a646aee3b2527f_264x22.jpg)
are the same set—namely, the set of the first four positive integers. Another example of a set is
![](https://box.kancloud.cn/7d5ee4541e1e69dbae62aea16a1378d9_360x23.jpg)
This is the set of the names of the days in the week. When a set is infinite, we can represent the set using a description of the objects in the set. For example, if we want to represent the set of positive integers that are integral multiples of 3, we can write
![](https://box.kancloud.cn/fefb43a2aad14aaaab52d64b0e96ecb2_400x21.jpg)
Alternatively, we can show some items and a general item, as follows:
![](https://box.kancloud.cn/60dd35410c06197126cfb0a399b2e128_176x22.jpg)
The objects in a set are called ***elements*** or ***members*** of the set. If *x* is an element of the set *S*, we write *x* ∊ *S*. If *x* is not an element of *S*, we write *x* ∉ *S*. For example,
![](https://box.kancloud.cn/57ce0ccc9040bea0d78cadb5c155fe0f_400x20.jpg)
We say that the sets *S* and *T* are equal if they have the same elements, and we write *S* = *T*. If they are not equal, we write *S* ≠ *T*. For example,
![](https://box.kancloud.cn/8962f9d3f315daa1474d677fd34e49c7_400x17.jpg)
If *S* and *T* are two sets such that every element in *S* is also in *T*, we say that *S* is a ***subset*** of *T*, and we write *S* ⊆ *T*. For example,
![](https://box.kancloud.cn/56bcc90a7eb967ebe82afc09a143df25_400x17.jpg)
Every set is a subset of itself. That is, for any set *S*, *S* ⊆ *S*. If *S* is a subset of *T* that is not equal to *T*, we say that *S* is a ***proper subset*** of *T*, and we write *S* ⊂ *T*. For example,
![](https://box.kancloud.cn/ce85f30044c5371d6c5c7411438d6446_400x16.jpg)
For two sets *S* and *T*, the ***intersection*** of *S* and *T* is defined as the set of all elements that are in both *S* and *T*. We write *S* ∩ *T*. For example,
![](https://box.kancloud.cn/7eb969ec770c11d6809630d65c60452a_400x16.jpg)
For two sets *S* and *T*, the ***union*** of *S* and *T* is defined as the set of all elements that are in either *S* or *T*. We write *S* ∪ *T*. For example,
![](https://box.kancloud.cn/b46903d27c6af86d5681a9267d032e8e_400x15.jpg)
For two sets *S* and *T*, the ***difference*** between *S* and *T* is defined as the set of all elements that are in *S* but not in *T*. We write *S* − *T*. For example,
![](https://box.kancloud.cn/ba1ffdb3f444936bcbf049b63eaad507_400x38.jpg)
The ***empty set*** is defined as the set containing no elements. We denote the empty set by Ø.
![](https://box.kancloud.cn/5c74ff4b641f0b5c2e2c098cd2415d7b_400x17.jpg)
The ***universal set*** *U* is defined as the set consisting of all elements under consideration. This means that if *S* is any set we are considering, then *S* ⊆ *U*. For example, if we are considering sets of positive integers, then
![](https://box.kancloud.cn/cc6dff808d94a64b92b3ea3dc4573225_189x23.jpg)
- Table of Contents
- BackCover
- Foundations of Algorithms Using C++ Pseudocode, Third Edition
- Preface
- Chapter Contents
- Pedagogy
- Course Outlines
- Acknowledgments
- Errors
- Chapter 1: Algorithms - Efficiency, Analysis, and Order
- 1.2 The Importance of Developing Efficient Algorithms
- 1.3 Analysis of Algorithms
- 1.4 Order
- 1.5 Outline of This Book
- Exercises
- Chapter 2: Divide-and-Conquer
- 2.1 Binary Search
- 2.2 Mergesort
- 2.3 The Divide-and-Conquer Approach
- 2.4 Quicksort (Partition Exchange Sort)
- 2.5 Strassen's Matrix Multiplication Algorithm
- 2.6 Arithmetic with Large Integers
- 2.7 Determining Thresholds
- 2.8 When Not to Use Divide-and-Conquer
- Exercises
- Chapter 3: Dynamic Programming
- 3.1 The Binomial Coefficient
- 3.2 Floyd's Algorithm for Shortest Paths
- 3.3 Dynamic Programming and Optimization Problems
- 3.4 Chained Matrix Multiplication
- 3.5 Optimal Binary Search Trees
- 3.6 The Traveling Salesperson Problem
- Exercises
- Chapter 4: The Greedy Approach
- 4.1 Minimum Spanning Trees
- 4.2 Dijkstra's Algorithm for Single-Source Shortest Paths
- 4.3 Scheduling
- 4.4 Huffman Code
- 4.5 The Greedy Approach versus Dynamic Programming: The Knapsack Problem
- Exercises
- Chapter 5: Backtracking
- 5.2 The n-Queens Problem
- 5.3 Using a Monte Carlo Algorithm to Estimate the Efficiency of a Backtracking Algorithm
- 5.4 The Sum-of-Subsets Problem
- 5.5 Graph Coloring
- 5.6 The Hamiltonian Circuits Problem
- 5.7 The 0-1 Knapsack Problem
- Exercises
- Chapter 6: Branch-and-Bound
- 6.1 Illustrating Branch-and-Bound with the 0 - 1 Knapsack problem
- 6.2 The Traveling Salesperson Problem
- 6.3 Abductive Inference (Diagnosis)
- Exercises
- Chapter 7: Introduction to Computational Complexity - The Sorting Problem
- 7.2 Insertion Sort and Selection Sort
- 7.3 Lower Bounds for Algorithms that Remove at Most One Inversion per Comparison
- 7.4 Mergesort Revisited
- 7.5 Quicksort Revisited
- 7.6 Heapsort
- 7.6.1 Heaps and Basic Heap Routines
- 7.6.2 An Implementation of Heapsort
- 7.7 Comparison of Mergesort, Quicksort, and Heapsort
- 7.8 Lower Bounds for Sorting Only by Comparison of Keys
- 7.8.1 Decision Trees for Sorting Algorithms
- 7.8.2 Lower Bounds for Worst-Case Behavior
- 7.8.3 Lower Bounds for Average-Case Behavior
- 7.9 Sorting by Distribution (Radix Sort)
- Exercises
- Chapter 8: More Computational Complexity - The Searching Problem
- 8.1 Lower Bounds for Searching Only by Comparisons of Keys
- 8.2 Interpolation Search
- 8.3 Searching in Trees
- 8.4 Hashing
- 8.5 The Selection Problem: Introduction to Adversary Arguments
- Exercises
- Chapter 9: Computational Complexity and Interactability - An Introduction to the Theory of NP
- 9.2 Input Size Revisited
- 9.3 The Three General Problem Categories
- 9.4 The Theory of NP
- 9.5 Handling NP-Hard Problems
- Exercises
- Chapter 10: Number-Theoretic Algorithms
- 10.1 Number Theory Review
- 10.2 Computing the Greatest Common Divisor
- 10.3 Modular Arithmetic Review
- 10.4 Solving Modular Linear Equations
- 10.5 Computing Modular Powers
- 10.6 Finding Large Prime Numbers
- 10.7 The RSA Public-Key Cryptosystem
- Exercises
- Chapter 11: Introduction to Parallel Algorithms
- 11.1 Parallel Architectures
- 11.2 The PRAM Model
- Exercises
- Appendix A: Review of Necessary Mathematics
- A.2 Functions
- A.3 Mathematical Induction
- A.4 Theorems and Lemmas
- A.5 Logarithms
- A.6 Sets
- A.7 Permutations and Combinations
- A.8 Probability
- Exercises
- Appendix B: Solving Recurrence Equations - With Applications to Analysis of Recursive Algorithms
- B.2 Solving Recurrences Using the Characteristic Equation
- B.3 Solving Recurrences by Substitution
- B.4 Extending Results for n, a Power of a Positive Constant b, to n in General
- B.5 Proofs of Theorems
- Exercises
- Appendix C: Data Structures for Disjoint Sets
- References
- Index
- Index_B
- Index_C
- Index_D
- Index_E
- Index_F
- Index_G
- Index_H
- Index_I
- Index_J
- Index_K
- Index_L
- Index_M
- Index_N
- Index_O
- Index_P
- Index_Q
- Index_R
- Index_S
- Index_T
- Index_U
- Index_V
- Index_W-X
- Index_Y
- Index_Z
- List of Figures
- List of Tables
- List of Algorithms, Examples, and Theorems
- List of Sidebars