This document introduces binary trees and provides a series of practice problems of increasing difficulty related to binary trees. It begins with an introduction to binary tree structure and terminology. It then provides 14 binary tree problems with descriptions and hints for solving each problem. The problems involve tasks like counting nodes, finding minimum/maximum values, printing trees in different orders, checking for paths with a given sum, and printing all root-to-leaf paths. Sample solutions are provided in subsequent sections in C/C++ and Java languages.
Class lecture of Data Structure and Algorithms and Python.
Stack, Queue, Tree, Python, Python Code, Computer Science, Data, Data Analysis, Machine Learning, Artificial Intellegence, Deep Learning, Programming, Information Technology, Psuedocide, Tree, pseudocode, Binary Tree, Binary Search Tree, implementation, Binary search, linear search, Binary search operation, real-life example of binary search, linear search operation, real-life example of linear search, example bubble sort, sorting, insertion sort example, stack implementation, queue implementation, binary tree implementation, priority queue, binary heap, binary heap implementation, object-oriented programming, def, in BST, Binary search tree, Red-Black tree, Splay Tree, Problem-solving using Binary tree, problem-solving using BST, inorder, preorder, postorder
The document discusses binary trees and binary search trees. It defines key terms like root, child, parent, leaves, height, depth. It explains tree traversal methods like preorder, inorder and postorder. It then describes binary search trees and how they store keys in a way that searching, insertion and deletion can be done efficiently in O(log n) time. It discusses implementation of operations like search, insert, delete on BSTs. It introduces balanced binary search trees like AVL trees that ensure height is O(log n) through rotations during insertions and deletions.
A binary tree is composed of nodes where each node contains a value and pointers to its left and right children. A binary tree traversal involves systematically visiting each node by traversing either breadth-first or depth-first. Breadth-first traversal visits nodes by level while depth-first traversal can be pre-order, in-order, or post-order depending on when the node is visited. Threaded binary trees reduce the number of null pointers by using them to point to other nodes for more efficient traversals.
This document discusses binary search trees. It begins by defining what a binary tree is, noting that each node can have up to two child nodes and there is a unique path from the root node to every other node. Some key terminology introduced includes leaf nodes, parent and child nodes, levels, height, and full trees.
The document then explains that binary search trees have the property that for each node, all values in its left subtree are less than the node's value and all values in its right subtree are greater. This property enables searching a binary search tree to have an average-case running time of O(logN). Several tree traversal orders - preorder, inorder and postorder - are also covered. The document concludes
Introduction, Array of structure, Passing structure to function, Passing array of structure to function, Structure within structure ( Nested Structure), Union, Pointer to structure
A binary search tree is a node-based binary tree data structure where each node contains a key and a value. Each node has references to its left and right child nodes. Common operations on a binary search tree include search, insert, preorder traversal, inorder traversal, and postorder traversal. During a search, the tree is traversed starting from the root node by comparing keys to determine whether to search in the left or right subtree. Insertion adds new nodes at leaf locations. Traversals have different orders for visiting the left subtree, root, and right subtree.
Tree and Binary search tree in data structure.
The complete explanation of working of trees and Binary Search Tree is given. It is discussed such a way that everyone can easily understand it. Trees have great role in the data structures.
Binary trees are a data structure where each node has at most two children. A binary tree node contains data and pointers to its left and right child nodes. Binary search trees are a type of binary tree where nodes are organized in a manner that allows for efficient searches, insertions, and deletions of nodes. The key operations on binary search trees are searching for a node, inserting a new node, and deleting an existing node through various algorithms that traverse the tree. Common traversals of binary trees include preorder, inorder, and postorder traversals.
When to use a structure vs classes in c++Naman Kumar
This document contains 20 questions related to C# programming. The questions cover a variety of topics such as when to use structs vs classes, parsing XML files, checking if a number is a power of 2, getting the index of a foreach loop iteration, rounding decimals, removing duplicates from arrays, sorting dictionaries by value, and returning multiple values from a function.
Binary search trees (BSTs) are data structures that allow for efficient searching, insertion, and deletion. Nodes in a BST are organized so that all left descendants of a node are less than the node's value and all right descendants are greater. This property allows values to be found, inserted, or deleted in O(log n) time on average. Searching involves recursively checking if the target value is less than or greater than the current node's value. Insertion follows the search process and adds the new node in the appropriate place. Deletion handles three cases: removing a leaf, node with one child, or node with two children.
The document discusses C programming concepts including structures, unions, and data types. It covers defining and using structures, with examples of declaring structure variables, initializing members, accessing members, structure assignment, arrays of structures, and structures within structures. It also discusses defining and using unions, and provides an example union definition and memory allocation. The document is made up of multiple lectures on these topics presented in Busy Bee workshops.
THREADED BINARY TREE AND BINARY SEARCH TREESiddhi Shrivas
The document discusses threaded binary trees. It begins by defining a regular binary tree. It then explains that in a threaded binary tree, null pointers are replaced by threads (pointers) to other nodes. Threading rules specify that a null left/right pointer is replaced by a pointer to the inorder predecessor/successor. Boolean fields distinguish threads from links. Non-recursive traversals are possible by following threads. Insertion and deletion of nodes may require updating threads. Threaded binary trees allow efficient non-recursive traversals without a stack.
The document discusses binary trees, including their terminology, implementation, operations, and traversal methods. It lists the group members and then defines key binary tree concepts like nodes, children, parents, roots, and leaf nodes. It explains that a binary tree has at most two children per node, and describes how to implement one using linked lists. Common binary tree operations like searching, insertion, deletion, creation, and traversing are then covered with examples. The different traversal orders - preorder, inorder, postorder, and level order - are defined along with examples.
1) The document discusses different aspects of structures in C programming such as defining a structure, initializing structures, accessing structure members, arrays of structures, nested structures, and pointers to structures.
2) A structure allows grouping of different data types under a single name and is useful for representing records with multiple attributes of an entity.
3) Structures can contain other structures to represent nested relationships between entities. Pointers to structures allow structures to be passed to functions and returned from functions.
1. A structure is a collection of variables under a single name. Variables within a structure can be of different data types like int, float, etc.
2. To declare a structure, the keyword struct is used followed by the structure name in braces. To define a structure variable, the data type is the structure name followed by the variable name.
3. Structure members are accessed using the dot operator between the structure variable name and member name.
This document discusses trees as a data structure. It defines trees as structures containing nodes where each node can have zero or more children and at most one parent. Binary trees are defined as trees where each node has at most two children. The document discusses tree terminology like root, leaf, and height. It also covers binary search trees and their properties for storing and searching data, as well as algorithms for inserting and deleting nodes. Finally, it briefly discusses other types of trees like balanced search trees and parse trees.
The document discusses arrays and data structures in Java. It explains that wrapping an array in a class hides implementation details and provides an interface for users. This abstraction makes the code easier to design. It also describes how ordered arrays allow faster searching through binary search but slower insertion compared to unordered arrays. The document provides code examples for an ordered array class that implements binary search and shows how to store objects like Person data in an array.
The document discusses structures in C programming. It defines a structure as a collection of variables of different data types grouped together under a single name. Structures allow programmers to create custom data types by combining existing types. The document provides examples of defining, declaring, initializing and accessing members of structures, and also discusses arrays of structures and nested structures.
This document contains a summary of structures in C programming language. It defines what a structure is, how to declare and define a structure with members, and how to access structure members using the dot operator. It also discusses nested structures, arrays of structures, and provides an example of a program that uses a structure to prepare student mark statements. Key points covered include declaring and defining structures, accessing structure members, nested structures, arrays of structures, and an example program to print student marks statements using a structure.
Este documento describe la experiencia de Chile en la protección de la salud mental luego del terremoto y tsunami del 27 de febrero de 2010. Explica que los desastres pueden tener efectos negativos en la salud mental de la población afectada y que es importante abordarlos. También describe las acciones de preparación del Ministerio de Salud de Chile antes del desastre y las intervenciones realizadas durante las etapas crítica, post-crítica y de recuperación para proteger la salud mental de los afectados.
El documento presenta los componentes clave de un plan de negocios para una empresa de servicios financieros. Describe su estrategia de marketing en dos etapas, la primera enfocada en mejorar su imagen corporativa y la segunda en penetrar nuevos mercados mediante la segmentación, diferenciación de productos y campañas publicitarias. También incluye secciones sobre la estructura del curso de plan de negocios y conceptos generales.
El documento resume los componentes, fortalezas y oportunidades de mejora de la gestión directiva de una institución educativa. Identifica que la institución cuenta con una misión, visión y principios definidos, así como metas establecidas, pero que algunas de estas metas y su direccionamiento estratégico no están claramente articulados. Señala también que la institución debe mejorar la evaluación y articulación de sus planes, proyectos, acciones y estrategias pedagógicas con su misión y visión, así como el uso sistemático de inform
1ºBACH ECONOMÍA Repaso temas 5 6-7 (gh23)Geohistoria23
Este documento explica los conceptos básicos de la demanda y la oferta. Resume que la curva de demanda muestra la relación negativa entre el precio y la cantidad demandada de un bien, mientras que la curva de oferta muestra la relación positiva entre el precio y la cantidad ofrecida. También describe los factores que afectan a la demanda y la oferta, así como los tipos de modificaciones que pueden ocurrir a las curvas (movimientos y desplazamientos).
The document provides tips for writing effective error messages that do not blame the user but take responsibility, speak in plain language the user understands, specifically identify the problem, try to fix it if possible, give clear instructions, and communicate that the problem is being taken seriously. It also includes further reading on designing helpful error messages.
Gfpi f-019 guia de aprendizaje 01 tda orientar fpilisbet bravo
Este documento presenta una guía de aprendizaje para un proyecto de formación profesional integral en el Servicio Nacional de Aprendizaje (SENA) de Colombia. La guía describe las actividades de aprendizaje, los materiales requeridos, y los criterios de evaluación. El objetivo del proyecto es analizar variables contextuales que influyen en la formación profesional para desarrollar competencias acordes a las necesidades sociales y productivas.
Este documento presenta las directrices para realizar un Análisis Situacional Integral de Salud (ASIS) en Ecuador. El ASIS es una herramienta que permite caracterizar la situación de salud de una población y analizar los determinantes sociales que afectan la salud. El proceso del ASIS incluye producir un diagnóstico situacional inicial, conformar un comité local de salud, priorizar problemas, elaborar un plan local de salud, e implementar y dar seguimiento al plan. El objetivo es mejorar la gestión de salud a través de la particip
JULIOPARI - Elaborando un Plan de NegociosJulio Pari
Este documento presenta un bosquejo de curso para elaborar un plan de negocios. El curso consta de 10 secciones que explican conceptos clave como la misión, visión, objetivos, clientes, competidores y proyecciones financieras. El curso ayudará a los participantes a comprender qué es un plan de negocios y cómo crear uno efectivo para diferentes propósitos como obtener financiamiento. El bosquejo resume brevemente el contenido de cada sección con el fin de guiar a los estudiantes en la elaboración exitosa de su propio plan de neg
El emprendedor y el empresario profesional certMaestros Online
Este documento proporciona información sobre un servicio de asesoría y resolución de ejercicios para estudiantes. Incluye instrucciones para actividades individuales y colaborativas relacionadas con temas de emprendimiento, como definir ventajas y desventajas de pequeñas empresas, comparar características de empresarios tradicionales y profesionales, y desarrollar ideas de negocio. También incluye preguntas sobre pasiones personales y admiración por figuras públicas.
1ºBACH Economía Tema 5 Oferta y demandaGeohistoria23
Este documento contiene información sobre conceptos económicos como demanda, oferta, curvas de demanda y oferta, y factores que afectan la demanda y la oferta. Incluye correos electrónicos, enlaces a blogs, tablas y gráficos explicativos. Aborda temas como la ley de la demanda decreciente, la curva de demanda individual y de mercado, y los factores que pueden causar desplazamientos o movimientos a lo largo de las curvas de demanda y oferta.
The poem is about hiding tears and sadness from a parting lover by pretending the tears are just rain. The speaker is saying goodbye but will appear unaffected because "you can't see tears in the rain." They will cry in vain and the other person will never know their pain or see that it matters to them. The rain provides cover for the speaker's true emotions as they turn the page and let go of the relationship.
Este plan de negocios describe una compañía que ofrece [PRODUCTO O SERVICIO]. Detalla el mercado, la competencia y la estrategia de marketing. El equipo de administración tiene experiencia relevante. Se requiere capital para establecer operaciones y alcanzar las metas de ventas proyectadas en los primeros años. De ser exitoso, este negocio podría [BENEFICIO FINAL].
This document introduces binary trees and provides sample code for basic operations like lookups and inserts. It discusses the structure of binary trees, with nodes containing left/right pointers and data. Binary search trees require that all left subtree nodes are less than the parent and right greater. Sample C/C++ code is given for lookup and insert functions that demonstrate the recursive traversal and modification of the tree. The document aims to prepare the reader to solve practice problems of increasing difficulty involving binary trees and pointers.
This document provides an introduction and 18 problems related to linked lists of increasing difficulty. It begins with a review of basic linked list code techniques, such as iterating through a list and adding/removing nodes. The problems cover a wide range of skills with pointers and complex algorithms. Though linked lists are not commonly used today, they are excellent for developing skills with complex pointer-based data structures and algorithms. The document provides solutions to all problems to help readers practice and learn.
The document discusses different types of binary tree traversal including inorder, preorder, and postorder traversal. It provides C code examples to perform each type of traversal on a binary search tree. The code inserts nodes into the tree, then performs the specified traversal by recursively navigating the tree and printing out the node values at each step according to the traversal type. Sample output is shown for building a binary search tree and performing various traversals on it by selecting options from a menu.
This document discusses binary trees as a data structure for storing hierarchical data. It defines key tree terminology like root, parent, child, and leaf nodes. It provides examples of how binary trees can be used to represent expressions and for file compression. It also introduces a BinaryTreeNode inner class to represent individual nodes, with constructors to initialize the data, left, and right references. Code is provided to build sample trees from these nodes and an example recursive size method is given.
Please i need help on following program using C++ Language.Add the.pdfezzi552
Instructions write a c program to solve the following problem. Upload your source code file to
Canvas. The file name must be of the form hwloop your name.c Substitute your first and last
name for \"your name\" in the file name. Example: Student\'s name is Sparky Watts. The file
name is hwloop sparky watts.c Problem Statement create a program that calculates twelve
month\'s interest and principle loan balance. Your program will ask the user for the starting
principle balance, annual interest rate, and monthly payment amount. Your program will verify
the input is reasonable, as described in the Error checking section below. After obtaining
reasonable the program will process 12 months of payments. The will show the accrued interest
and updated loan balance after each month\'s payment. The total interest paid and total payment
amounts for the 12 month period will also be calculated and displayed. Your program output
should resemble the output below. AUsers williidialDesktoplhw04MbinlDebuglhw04.exe Enter
loan anount: 32000.00 Enter annual interest rate 7.99 Enter monthly payment 752.84
Solution
#include
#include
int main()
{
double loan_amount = 0;
printf(\"Enter loan amount :\");
if (scanf(\"%lf\", &loan_amount) != 1)
{
printf(\"Please enter loan amount correctly\ \");
return -1;
}
if (loan_amount < 500)
{
printf(\"Loan amount should be greater than 500\ \");
return 1;
}
if (loan_amount > 100000)
{
printf(\"Loan amount should be less than 100000\ \");
return -1;
}
printf(\"Enter annual interest rate: \");
double interest_rate;
if (scanf(\"%lf\", &interest_rate) != 1)
{
printf(\"Please enter interest rate correctly\ \");
return -1;
}
if (interest_rate < 0 || interest_rate > 8.99)
{
printf(\"Interest rate should be in range of 0 to 8.99\ \");
return -1;
}
double monthly_payments;
printf(\"Enter monthly payment: \");
if (scanf(\"%lf\", &monthly_payments) != 1)
{
printf(\"Please monthly payment correctly\ \");
return -1;
}
double first_month_interest = (loan_amount * interest_rate)/(12*100);
if (monthly_payments < first_month_interest)
{
printf(\"Monthly payment should be greater than %f\ \", first_month_interest);
return -1;
}
double total_interest = 0;
double total_paid = 0;
printf(\"\ \");
printf(\"Begin \\t\\t\\t\\tMonthly\\tEnd\ \");
printf(\"Loan\\t\\tAccured\\t\\tPayment\\tLoan\ \");
printf(\"Balance\\t\\tInterest\\tAmount\\tBalance\ \");
printf(\"\ \");
int i;
for(i = 0; i <= 12; i++)
{
printf(\"%0.2f\\t\", loan_amount);
double interest = (loan_amount*interest_rate)/(1200);
printf(\"%0.2f\\t\\t\", interest);
printf(\"%0.2f\\t\", monthly_payments);
loan_amount = loan_amount + interest;
if (loan_amount < monthly_payments)
{
total_paid -= loan_amount;
loan_amount = 0;
printf(\"%0.2f\ \", loan_amount);
break;
}
else
{
loan_amount -= monthly_payments;
total_paid += monthly_payments;
}
printf(\"%0.2f\ \", loan_amount);
total_interest += interest;
}
printf(\"\ \");
printf(\"Annual total\\t%.2f\\t\\t%.2f\ \", total_interest, total_paid);
return 0;
}.
A linked list is a data structure that stores elements non-contiguously in memory. Each element contains a data field and a pointer to the next element. Linked lists allow dynamic sizes and efficient insertion/deletion compared to arrays. This document introduces linked lists using C code examples to build a sample list and functions to get its length. Key concepts are using pointers to connect nodes allocated in the heap, representing empty lists with NULL, and iterating lists by following next pointers from a local pointer variable.
1. The document defines and provides examples of various data structures including lists, stacks, queues, trees, and their properties.
2. Key concepts covered include linear and non-linear data structures, common tree types, tree traversals, and operations on different data structures like insertion, deletion, and searching.
3. Examples are provided to illustrate concepts like binary search trees, tree representation and traversal methods.
Assg 12 Binary Search TreesCOSC 2336 Spring 2019April.docxfestockton
Assg 12: Binary Search Trees
COSC 2336 Spring 2019
April 10, 2019
Dates:
Due: Sunday April 21, by Midnight
Objectives
� Practice recursive algorithms
� Learn how to construct a binary tree using pointers/linked nodes
� Learn about binary tree traversal
Description
In this assignment you will be given the beginning of a BinaryTree imple-
mentation using linked nodes via pointers. You will be implementing some
of the basic function of a BinaryTree abstract data type. The abstraction
we are using for the BinaryTreeNode and the BinaryTree are similar to
the Sha�er BSTNode (pg. 156,161) and the BST abstract class and linked
pointer implementation (Sha�er pg. 171), but we will de�ne our own version
and simplify some of the functions and interface.
You have been given a BinaryTree.[cpp|hpp] �le that de�nes the BinaryTreeNode
structure and BinaryTree class. This class is current not templatized, the
constructed trees only hold items of simple type int (one of the extra credit
opportunities suggests you templatize your resulting class). The BinaryTree
has a constructor, and you have been provided a tostring() method and
an overloaded operator�() so that you can display the current contents of
the tree.
For this assignment you need to perform the following tasks.
1
1. In order to test your class, we �rst have to get a working capability to
insert new items into the BinaryTree, which isn't the simplest task to
start with, but we can't really test others until we can add new items.
For many of the functions in this assignment, you will be required to
implement them using a recursive function. Thus many of the func-
tions for your BinaryTree will have a public function that asks as the
interface that is called by users of the BinaryTree, and a private ver-
sion that actually does the work using a recursive algorithm. I will
give you the signature you need for the insert() functions:
class BinaryTree
{
private:
BinaryTreeNode* insert(BinaryTreeNode* node, const int item);
public:
void insert(const int item);
}
Lets start �rt with the public insert() function. This function is the
public interface to insert a new item into the tree. Since we are only
implementing a tree of int items, you simply pass in the int value that
is to be inserted. This function basically only needs to call the private
insert() function, passing in the current root of the tree as the �rst
parameter, and the item to be inserted as the second parameter. Notice
that the private insert() returns a pointer to a BinaryTreeNode.
The private insert() function is a recursive function. The base case
is simple. If the node you pass in is NULL, then that means you have
found the location where a new node should be created and inserted.
So for the base case, when node is NULL you should dynamically create
a new BinaryTreeNode item, assign the item and make sure that the
left and right pointers are initialized to NULL. When you create a new
node like this, you should retu ...
Modularity is the degree to which a system's components can be separated and recombined. Modular programming separates a program into independent, interchangeable modules that contain everything needed to execute one aspect of functionality. This allows for less code, easier collaboration, and easier identification and fixing of errors. A queue is a first-in, first-out data structure that can be implemented using a linked list. The advantages of a linked representation over a linear representation for trees include easier insertion and deletion without data movement and flexibility in memory allocation.
Counting and sorting are basic tasks that distributed systems rely on. The document discusses different approaches for distributed counting and sorting, including software combining trees, counting networks, and sorting networks. Counting networks like bitonic and periodic networks have depth of O(log2w) where w is the network width. Sorting networks can sort in the same time complexity by exploiting an isomorphism between counting and sorting networks. Sample sorting is also discussed as a way to sort large datasets across multiple threads.
1) The document describes writing an MPI program to calculate a quantity called coverage from data files in a distributed manner across a cluster.
2) MPI (Message Passing Interface) is a standard for writing programs that can run in parallel on multiple processors. The program should distribute the computation efficiently across the cluster nodes and yield the same results as a serial code.
3) The MPI program structure involves initialization, processes running concurrently on nodes, communication between processes, and finalization. Communicators define which processes can communicate.
Consider this code using the ArrayBag of Section 5.2 and the Locat.docxmaxinesmith73660
Consider this code using the ArrayBag of Section 5.2 and the Location class from Chapter 2. What is the output?
Location i = new Location(0, 3);
Location j = new Location(0, 3);
b.add(i);
b.add(j);
System.out.println(b.countOccurrences(i));
A. 0
B. 1
C. 2
D. 3
Suppose that b and c are Integer objects. A typical use of the clone method looks like this:
b = (Integer) c.clone( );
Write a short clear explanation of why the (Integer) type cast is required in this typical example.
A. obj = s;
B. s = obj;
C. s = (String) obj;
D. Two or more answers are correct.
Suppose that obj is an Object variable and s is a String variable. Which of the following statements
is a correctly-compiling widening conversion? Don't worry about possible run-time exceptions
A. obj = s;
B. s = obj;
C. s = (String) obj;
D. Two or more answers are correct.
Suppose that x and y are reference variables and a program activates x.equals(y). What occurs if x is the null reference?
A. A NullPointerException occurs
B. It always returns true.
C. It always returns false.
D. It returns true if y is also a null reference; otherwise it returns false.
Consider the implementation of the Stack using a partially-filled array.
What goes wrong if we try to store the top of the Stack at location [0] and the bottom of the Stack at the last used position of the array?
A. Both peek and pop would require linear time.
B. Both push and pop would require linear time.
C. The Stack could not be used to check balanced parentheses.
D. The Stack could not be used to evaluate postfix expressions.
Write some lines of code that declares an Integer object, using the Integer wrapper class.
Assign the value 42 to this object, then copy this value from the Integer object to an ordinary int variable.
Consider the usual algorithm for determining whether a sequence of parentheses is balanced.
What is the maximum number of parentheses that will appear on the stack AT ANY ONE TIME when the algorithm analyzes: (()(())(()))?
A. 1
B. 2
C. 3
D. 4
E. 5 or more
Consider the usual algorithm to convert an infix expression to a postfix expression.
Suppose that you have read 10 input characters during a conversion and that the
stack now contains the symbols as shown below. Suppose that you read and process
the 11th symbol of the input. What symbol is at the top of the stack in the case where
the 11th symbol is each of the choices shown?
Which of the following stack operations could result in stack underflow?
Answer
A. is_empty
B. pop
C. push
D. Two or more of the above answers
What is the value of the postfix expression 6 3 2 4 + - *:
Answer
A. Something between -15 and -100
B. Something between -5 and -15
C. Something between 5 and -5
D. Something between 5 and 15
E. Something between 15 and 100
1. An array o.
The document discusses different data structures and their implementations and applications. It covers arrays, linked lists, stacks, queues, binary trees, and binary search. The key points are:
- Arrays allow fast access but have fixed size; linked lists can grow dynamically but access is slower.
- Binary trees allow fast (O(log n)) search, insertion, and deletion operations due to their hierarchical structure.
- Stacks and queues are useful for modeling LIFO and FIFO data access with applications like function calls and job scheduling.
- Binary search runs in O(log n) time by recursively dividing the search space for sorted data.
Binary search trees are binary trees where all left descendants of a node are less than the node's value and all right descendants are greater. This structure allows for efficient search, insertion, and deletion operations. The document provides definitions and examples of binary search tree properties and operations like creation, traversal, searching, insertion, deletion, and finding minimum and maximum values. Applications include dynamically maintaining a sorted dataset to enable efficient search, insertion, and deletion.
This document defines and provides examples of trees and binary trees. It begins by defining trees as hierarchical data structures with nodes and edges. It then provides definitions for terms like path, forest, ordered tree, height, and multiway tree. It specifically defines binary trees as having two children per node. The document gives examples and properties of binary trees, including full, complete, and binary search trees. It also explains linear and linked representations of binary trees and different traversal methods like preorder, postorder and inorder. Finally, it provides examples of insertion and deletion operations in binary search trees.
This document discusses binary search trees in Python. It defines a binary search tree as a data structure where every node has at most two children, with the left child being smaller than the parent and right child being larger. It describes key properties like unique values, efficient insertion/deletion, and tree traversal flexibility. It then provides code examples for a Node class, insertion/deletion implementations, and searching a tree for a node. Finally, it discusses balancing binary search trees to maintain optimal time complexities.
Taylor Lovett is a senior web engineer who studied computer science. Computer science involves the study of computational theory, software, and hardware. It includes topics like algorithms, data structures, graph theory, programming, databases, and computer hardware. Big-O notation is used to describe how efficiently an algorithm solves a problem based on changes to input size. It indicates the worst-case time complexity of an algorithm. Tracking post views in WordPress can cause data race issues if not implemented carefully due to the possibility of concurrent requests updating the view count.
The document discusses trees and graphs data structures. It begins with introducing different types of trees like binary trees, binary search trees, threaded binary trees, and their various traversal algorithms like inorder, preorder and postorder traversals. It then discusses tree operations like copying trees, testing for equality. It also covers the satisfiability problem and how binary trees can be used to represent logical expressions to solve this problem. Finally, it discusses threaded binary trees where null links in a binary tree are replaced with threads, and how this allows for efficient inorder traversal in linear time.
This document discusses deques, priority queues, depth-first search (DFS), and breadth-first search (BFS). It provides code examples for deque and priority queue interfaces. It explains that a deque is a double-ended queue that allows adding/removing from both ends, while a priority queue organizes objects by priority rather than order of arrival. DFS searches deeper first until reaching a goal or dead end, while BFS searches all neighboring nodes first before moving to the next level. The document also discusses converting a general tree to a binary tree for efficient processing and traversal.
This document provides a tutorial on pointers and arrays in C. It begins by explaining that a pointer is a variable that holds the address of another variable. This allows a pointer variable to indirectly "point to" another variable in memory. The document covers various uses of pointers, including with arrays, strings, structures, dynamic memory allocation, and functions. It provides many code examples to demonstrate how pointers work in practice.
The document summarizes the M-tree, a new access method for organizing and searching large datasets in metric spaces. The M-tree is a balanced tree that partitions objects based on their relative distances as measured by a distance function, with objects stored in fixed-size nodes. It can index objects using arbitrary distance functions as long as they satisfy the metric properties. The M-tree aims to reduce both the number of accessed nodes and distance computations needed for similarity queries, improving performance for CPU-intensive distance functions. Algorithms for range and k-nearest neighbor queries are described that leverage distance information stored in the M-tree to prune search spaces.
The document proposes an extension to the M-tree family of index structures called M*-tree. M*-tree improves upon M-tree by maintaining a nearest-neighbor graph within each node. The nearest-neighbor graph stores, for each entry in a node, a reference and distance to its nearest neighbor among the other entries in that node. This additional structure allows for more efficient filtering of non-relevant subtrees during search queries through the use of "sacrifice pivots". The experiments showed that M*-tree can perform searches significantly faster than M-tree while keeping construction costs low.
The document describes the PM-tree, a new metric access method that combines the M-tree with pivot-based approaches to improve efficiency of similarity search in multimedia databases. The PM-tree enhances M-tree routing and ground entries by including pivot-based information like hyper-ring regions defined by pivot objects and distances. This reduces the volume of metric regions described by entries, tightly bounding indexed objects and improving retrieval performance. Algorithms for building and querying the PM-tree are presented, showing how pivot distances are used to prune irrelevant regions during search.
c language faq's contains the frequently asked questions in c language and useful for all c programmers. This is an pdf document of Sterve_summit who is one of the best writer for c language
The document defines the User Datagram Protocol (UDP) which provides a minimal datagram mode of communication using the Internet Protocol and allows applications to send messages with minimal overhead, though delivery is not guaranteed like with TCP. UDP uses port numbers and IP addresses in packet headers and optional checksums to provide some protection against misrouted packets. Major applications that use UDP include the Internet Name Server and Trivial File Transfer.
The document provides an overview of the Stream Control Transmission Protocol (SCTP). SCTP is a connection-oriented transport layer protocol that offers reliable data transfer over IP networks. It supports features like multihoming for network fault tolerance, multi-streaming to minimize delay, and congestion control. The document discusses SCTP's architecture, features, security mechanisms, and error handling. It is intended to help application developers write programs using SCTP socket APIs.
This ppt is html for beginners and html made easy for them to get the basic idea of html.
Html for beginners. A basic information of html for beginners. A more depth coverage of html and css will be covered in the future presentations. visit my sites http://technoexplore.blogspot.com and http://hotjobstuff.blogspot.com for some other important presentations.
Here are some interview tips for cracking the interview. During this recession period it is very important.
visit my sites http://technoexplore.blogspot.com and http://hotjobstuff.blogspot.com for some other important presentations.
queue datastructure made easy and datastructure explained in java. visit http://technoexplore.blogspot.com and http://hotjobstuff.blogspot.com for some other important presentations.
Html for beginners. A basic information of html for beginners. A more depth coverage of html and css will be covered in the future presentations. visit my sites http://technoexplore.blogspot.com and http://hotjobstuff.blogspot.com for some other important presentations.
Prim's algorithm is a greedy algorithm used to find minimum spanning trees for weighted undirected graphs. It operates by building the spanning tree one vertex at a time, from an arbitrary starting vertex, at each step adding the minimum weight edge that connects the growing spanning tree to a vertex not yet included in the tree. The algorithm repeats until all vertices are added.
The server containing programming assignments is located at 10.203.161.7 under the ~/CPP/ directory. The document outlines various C++ programming assignments divided across multiple sessions, including writing classes, operator overloading, inheritance, polymorphism, and more. Assignments involve concepts such as memory management, pass by reference, constructors/destructors, friend functions, and virtual functions.
Performance Budgets for the Real World by Tammy EvertsScyllaDB
Performance budgets have been around for more than ten years. Over those years, we’ve learned a lot about what works, what doesn’t, and what we need to improve. In this session, Tammy revisits old assumptions about performance budgets and offers some new best practices. Topics include:
• Understanding performance budgets vs. performance goals
• Aligning budgets with user experience
• Pros and cons of Core Web Vitals
• How to stay on top of your budgets to fight regressions
GDG Cloud Southlake #34: Neatsun Ziv: Automating AppsecJames Anderson
The lecture titled "Automating AppSec" delves into the critical challenges associated with manual application security (AppSec) processes and outlines strategic approaches for incorporating automation to enhance efficiency, accuracy, and scalability. The lecture is structured to highlight the inherent difficulties in traditional AppSec practices, emphasizing the labor-intensive triage of issues, the complexity of identifying responsible owners for security flaws, and the challenges of implementing security checks within CI/CD pipelines. Furthermore, it provides actionable insights on automating these processes to not only mitigate these pains but also to enable a more proactive and scalable security posture within development cycles.
The Pains of Manual AppSec:
This section will explore the time-consuming and error-prone nature of manually triaging security issues, including the difficulty of prioritizing vulnerabilities based on their actual risk to the organization. It will also discuss the challenges in determining ownership for remediation tasks, a process often complicated by cross-functional teams and microservices architectures. Additionally, the inefficiencies of manual checks within CI/CD gates will be examined, highlighting how they can delay deployments and introduce security risks.
Automating CI/CD Gates:
Here, the focus shifts to the automation of security within the CI/CD pipelines. The lecture will cover methods to seamlessly integrate security tools that automatically scan for vulnerabilities as part of the build process, thereby ensuring that security is a core component of the development lifecycle. Strategies for configuring automated gates that can block or flag builds based on the severity of detected issues will be discussed, ensuring that only secure code progresses through the pipeline.
Triaging Issues with Automation:
This segment addresses how automation can be leveraged to intelligently triage and prioritize security issues. It will cover technologies and methodologies for automatically assessing the context and potential impact of vulnerabilities, facilitating quicker and more accurate decision-making. The use of automated alerting and reporting mechanisms to ensure the right stakeholders are informed in a timely manner will also be discussed.
Identifying Ownership Automatically:
Automating the process of identifying who owns the responsibility for fixing specific security issues is critical for efficient remediation. This part of the lecture will explore tools and practices for mapping vulnerabilities to code owners, leveraging version control and project management tools.
Three Tips to Scale the Shift Left Program:
Finally, the lecture will offer three practical tips for organizations looking to scale their Shift Left security programs. These will include recommendations on fostering a security culture within development teams, employing DevSecOps principles to integrate security throughout the development
How Netflix Builds High Performance Applications at Global ScaleScyllaDB
We all want to build applications that are blazingly fast. We also want to scale them to users all over the world. Can the two happen together? Can users in the slowest of environments also get a fast experience? Learn how we do this at Netflix: how we understand every user's needs and preferences and build high performance applications that work for every user, every time.
Sustainability requires ingenuity and stewardship. Did you know Pigging Solutions pigging systems help you achieve your sustainable manufacturing goals AND provide rapid return on investment.
How? Our systems recover over 99% of product in transfer piping. Recovering trapped product from transfer lines that would otherwise become flush-waste, means you can increase batch yields and eliminate flush waste. From raw materials to finished product, if you can pump it, we can pig it.
Quality Patents: Patents That Stand the Test of TimeAurora Consulting
Is your patent a vanity piece of paper for your office wall? Or is it a reliable, defendable, assertable, property right? The difference is often quality.
Is your patent simply a transactional cost and a large pile of legal bills for your startup? Or is it a leverageable asset worthy of attracting precious investment dollars, worth its cost in multiples of valuation? The difference is often quality.
Is your patent application only good enough to get through the examination process? Or has it been crafted to stand the tests of time and varied audiences if you later need to assert that document against an infringer, find yourself litigating with it in an Article 3 Court at the hands of a judge and jury, God forbid, end up having to defend its validity at the PTAB, or even needing to use it to block pirated imports at the International Trade Commission? The difference is often quality.
Quality will be our focus for a good chunk of the remainder of this season. What goes into a quality patent, and where possible, how do you get it without breaking the bank?
** Episode Overview **
In this first episode of our quality series, Kristen Hansen and the panel discuss:
⦿ What do we mean when we say patent quality?
⦿ Why is patent quality important?
⦿ How to balance quality and budget
⦿ The importance of searching, continuations, and draftsperson domain expertise
⦿ Very practical tips, tricks, examples, and Kristen’s Musts for drafting quality applications
https://www.aurorapatents.com/patently-strategic-podcast.html
Are you interested in dipping your toes in the cloud native observability waters, but as an engineer you are not sure where to get started with tracing problems through your microservices and application landscapes on Kubernetes? Then this is the session for you, where we take you on your first steps in an active open-source project that offers a buffet of languages, challenges, and opportunities for getting started with telemetry data.
The project is called openTelemetry, but before diving into the specifics, we’ll start with de-mystifying key concepts and terms such as observability, telemetry, instrumentation, cardinality, percentile to lay a foundation. After understanding the nuts and bolts of observability and distributed traces, we’ll explore the openTelemetry community; its Special Interest Groups (SIGs), repositories, and how to become not only an end-user, but possibly a contributor.We will wrap up with an overview of the components in this project, such as the Collector, the OpenTelemetry protocol (OTLP), its APIs, and its SDKs.
Attendees will leave with an understanding of key observability concepts, become grounded in distributed tracing terminology, be aware of the components of openTelemetry, and know how to take their first steps to an open-source contribution!
Key Takeaways: Open source, vendor neutral instrumentation is an exciting new reality as the industry standardizes on openTelemetry for observability. OpenTelemetry is on a mission to enable effective observability by making high-quality, portable telemetry ubiquitous. The world of observability and monitoring today has a steep learning curve and in order to achieve ubiquity, the project would benefit from growing our contributor community.
How to Avoid Learning the Linux-Kernel Memory ModelScyllaDB
The Linux-kernel memory model (LKMM) is a powerful tool for developing highly concurrent Linux-kernel code, but it also has a steep learning curve. Wouldn't it be great to get most of LKMM's benefits without the learning curve?
This talk will describe how to do exactly that by using the standard Linux-kernel APIs (locking, reference counting, RCU) along with a simple rules of thumb, thus gaining most of LKMM's power with less learning. And the full LKMM is always there when you need it!
Hire a private investigator to get cell phone recordsHackersList
Learn what private investigators can legally do to obtain cell phone records and track phones, plus ethical considerations and alternatives for addressing privacy concerns.
Paradigm Shifts in User Modeling: A Journey from Historical Foundations to Em...Erasmo Purificato
Slide of the tutorial entitled "Paradigm Shifts in User Modeling: A Journey from Historical Foundations to Emerging Trends" held at UMAP'24: 32nd ACM Conference on User Modeling, Adaptation and Personalization (July 1, 2024 | Cagliari, Italy)
AI_dev Europe 2024 - From OpenAI to Opensource AIRaphaël Semeteys
Navigating Between Commercial Ownership and Collaborative Openness
This presentation explores the evolution of generative AI, highlighting the trajectories of various models such as GPT-4, and examining the dynamics between commercial interests and the ethics of open collaboration. We offer an in-depth analysis of the levels of openness of different language models, assessing various components and aspects, and exploring how the (de)centralization of computing power and technology could shape the future of AI research and development. Additionally, we explore concrete examples like LLaMA and its descendants, as well as other open and collaborative projects, which illustrate the diversity and creativity in the field, while navigating the complex waters of intellectual property and licensing.
How RPA Help in the Transportation and Logistics Industry.pptxSynapseIndia
Revolutionize your transportation processes with our cutting-edge RPA software. Automate repetitive tasks, reduce costs, and enhance efficiency in the logistics sector with our advanced solutions.
Scaling Connections in PostgreSQL Postgres Bangalore(PGBLR) Meetup-2 - MydbopsMydbops
This presentation, delivered at the Postgres Bangalore (PGBLR) Meetup-2 on June 29th, 2024, dives deep into connection pooling for PostgreSQL databases. Aakash M, a PostgreSQL Tech Lead at Mydbops, explores the challenges of managing numerous connections and explains how connection pooling optimizes performance and resource utilization.
Key Takeaways:
* Understand why connection pooling is essential for high-traffic applications
* Explore various connection poolers available for PostgreSQL, including pgbouncer
* Learn the configuration options and functionalities of pgbouncer
* Discover best practices for monitoring and troubleshooting connection pooling setups
* Gain insights into real-world use cases and considerations for production environments
This presentation is ideal for:
* Database administrators (DBAs)
* Developers working with PostgreSQL
* DevOps engineers
* Anyone interested in optimizing PostgreSQL performance
Contact info@mydbops.com for PostgreSQL Managed, Consulting and Remote DBA Services
Quantum Communications Q&A with Gemini LLM. These are based on Shannon's Noisy channel Theorem and offers how the classical theory applies to the quantum world.
The DealBook is our annual overview of the Ukrainian tech investment industry. This edition comprehensively covers the full year 2023 and the first deals of 2024.
Data Protection in a Connected World: Sovereignty and Cyber Securityanupriti
Delve into the critical intersection of data sovereignty and cyber security in this presentation. Explore unconventional cyber threat vectors and strategies to safeguard data integrity and sovereignty in an increasingly interconnected world. Gain insights into emerging threats and proactive defense measures essential for modern digital ecosystems.
Data Protection in a Connected World: Sovereignty and Cyber Security
Binary Trees
1. Binary Trees Page: 1
Binary Trees
by Nick Parlante
This article introduces the basic concepts of binary trees, and then works through a series of practice problems with
solution code in C/C++ and Java. Binary trees have an elegant recursive pointer structure, so they are a good way to
learn recursive pointer algorithms.
Contents
Section 1. Binary Tree Structure -- a quick introduction to binary trees and the code that operates on them
Section 2. Binary Tree Problems -- practice problems in increasing order of difficulty
Section 3. C Solutions -- solution code to the problems for C and C++ programmers
Section 4. Java versions -- how binary trees work in Java, with solution code
Stanford CS Education Library -- #110
This is article #110 in the Stanford CS Education Library. This and other free CS materials are available at the
library (http://cslibrary.stanford.edu/). That people seeking education should have the opportunity to find it.
This article may be used, reproduced, excerpted, or sold so long as this paragraph is clearly reproduced. Copyright
2000-2001, Nick Parlante, nick.parlante@cs.stanford.edu.
Related CSLibrary Articles
Linked List Problems (http://cslibrary.stanford.edu/105/) -- a large collection of linked list problems
using various pointer techniques (while this binary tree article concentrates on recursion)
Pointer and Memory (http://cslibrary.stanford.edu/102/) -- basic concepts of pointers and memory
The Great Tree-List Problem (http://cslibrary.stanford.edu/109/) -- a great pointer recursion problem
that uses both trees and lists
Section 1 -- Introduction To Binary Trees
A binary tree is made of nodes, where each node contains a quot;leftquot; pointer, a quot;rightquot; pointer, and a data element.
The quot;rootquot; pointer points to the topmost node in the tree. The left and right pointers recursively point to smaller
quot;subtreesquot; on either side. A null pointer represents a binary tree with no elements -- the empty tree. The formal
recursive definition is: a binary tree is either empty (represented by a null pointer), or is made of a single node,
where the left and right pointers (recursive definition ahead) each point to a binary tree.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
2. Binary Trees Page: 2
A quot;binary search treequot; (BST) or quot;ordered binary treequot; is a type of binary tree where the nodes are arranged in order:
for each node, all elements in its left subtree are less-or-equal to the node (<=), and all the elements in its right
subtree are greater than the node (>). The tree shown above is a binary search tree -- the quot;rootquot; node is a 5, and its
left subtree nodes (1, 3, 4) are <= 5, and its right subtree nodes (6, 9) are > 5. Recursively, each of the subtrees must
also obey the binary search tree constraint: in the (1, 3, 4) subtree, the 3 is the root, the 1 <= 3 and 4 > 3. Watch out
for the exact wording in the problems -- a quot;binary search treequot; is different from a quot;binary treequot;.
The nodes at the bottom edge of the tree have empty subtrees and are called quot;leafquot; nodes (1, 4, 6) while the others
are quot;internalquot; nodes (3, 5, 9).
Binary Search Tree Niche
Basically, binary search trees are fast at insert and lookup. The next section presents the code for these two
algorithms. On average, a binary search tree algorithm can locate a node in an N node tree in order lg(N) time (log
base 2). Therefore, binary search trees are good for quot;dictionaryquot; problems where the code inserts and looks up
information indexed by some key. The lg(N) behavior is the average case -- it's possible for a particular tree to be
much slower depending on its shape.
Strategy
Some of the problems in this article use plain binary trees, and some use binary search trees. In any case, the
problems concentrate on the combination of pointers and recursion. (See the articles linked above for pointer articles
that do not emphasize recursion.)
For each problem, there are two things to understand...
The node/pointer structure that makes up the tree and the code that manipulates it
The algorithm, typically recursive, that iterates over the tree
When thinking about a binary tree problem, it's often a good idea to draw a few little trees to think about the
various cases.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
3. Binary Trees Page: 3
Typical Binary Tree Code in C/C++
As an introduction, we'll look at the code for the two most basic binary search tree operations -- lookup() and
insert(). The code here works for C or C++. Java programers can read the discussion here, and then look at the Java
versions in Section 4.
In C or C++, the binary tree is built with a node type like this...
struct node {
int data;
struct node* left;
struct node* right;
}
Lookup()
Given a binary search tree and a quot;targetquot; value, search the tree to see if it contains the target. The basic pattern of
the lookup() code occurs in many recursive tree algorithms: deal with the base case where the tree is empty, deal
with the current node, and then use recursion to deal with the subtrees. If the tree is a binary search tree, there is
often some sort of less-than test on the node to decide if the recursion should go left or right.
/*
Given a binary tree, return true if a node
with the target data is found in the tree. Recurs
down the tree, chooses the left or right
branch by comparing the target to each node.
*/
static int lookup(struct node* node, int target) {
// 1. Base case == empty tree
// in that case, the target is not found so return false
if (node == NULL) {
return(false);
}
else {
// 2. see if found here
if (target == node->data) return(true);
else {
// 3. otherwise recur down the correct subtree
if (target < node->data) return(lookup(node->left, target));
else return(lookup(node->right, target));
}
}
}
The lookup() algorithm could be written as a while-loop that iterates down the tree. Our version uses recursion to
help prepare you for the problems below that require recursion.
Pointer Changing Code
There is a common problem with pointer intensive code: what if a function needs to change one of the pointer
parameters passed to it? For example, the insert() function below may want to change the root pointer. In C and
C++, one solution uses pointers-to-pointers (aka quot;reference parametersquot;). That's a fine technique, but here we will
use the simpler technique that a function that wishes to change a pointer passed to it will return the new value of
the pointer to the caller. The caller is responsible for using the new value. Suppose we have a change() function
http://cslibrary.stanford.edu/110/
BinaryTrees.html
4. Binary Trees Page: 4
that may change the the root, then a call to change() will look like this...
// suppose the variable quot;rootquot; points to the tree
root = change(root);
We take the value returned by change(), and use it as the new value for root. This construct is a little awkward, but
it avoids using reference parameters which confuse some C and C++ programmers, and Java does not have reference
parameters at all. This allows us to focus on the recursion instead of the pointer mechanics. (For lots of problems
that use reference parameters, see CSLibrary #105, Linked List Problems, http://cslibrary.stanford.edu/105/).
Insert()
Insert() -- given a binary search tree and a number, insert a new node with the given number into the tree in the
correct place. The insert() code is similar to lookup(), but with the complication that it modifies the tree structure.
As described above, insert() returns the new tree pointer to use to its caller. Calling insert() with the number 5 on
this tree...
2
/
1 10
returns the tree...
2
/
1 10
/
5
The solution shown here introduces a newNode() helper function that builds a single node. The base-case/recursion
structure is similar to the structure in lookup() -- each call checks for the NULL case, looks at the node at hand, and
then recurs down the left or right subtree if needed.
/*
Helper function that allocates a new node
with the given data and NULL left and right
pointers.
*/
struct node* NewNode(int data) {
struct node* node = new(struct node); // quot;newquot; is like quot;mallocquot;
node->data = data;
node->left = NULL;
node->right = NULL;
return(node);
}
/*
Give a binary search tree and a number, inserts a new node
with the given number in the correct place in the tree.
Returns the new root pointer which the caller should
then use (the standard trick to avoid using reference
parameters).
*/
struct node* insert(struct node* node, int data) {
http://cslibrary.stanford.edu/110/
BinaryTrees.html
5. Binary Trees Page: 5
// 1. If the tree is empty, return a new, single node
if (node == NULL) {
return(newNode(data));
}
else {
// 2. Otherwise, recur down the tree
if (data <= node->data) node->left = insert(node->left, data);
else node->right = insert(node->right, data);
return(node); // return the (unchanged) node pointer
}
}
The shape of a binary tree depends very much on the order that the nodes are inserted. In particular, if the nodes
are inserted in increasing order (1, 2, 3, 4), the tree nodes just grow to the right leading to a linked list shape where
all the left pointers are NULL. A similar thing happens if the nodes are inserted in decreasing order (4, 3, 2, 1). The
linked list shape defeats the lg(N) performance. We will not address that issue here, instead focusing on pointers
and recursion.
Section 2 -- Binary Tree Problems
Here are 14 binary tree problems in increasing order of difficulty. Some of the problems operate on binary search
trees (aka quot;ordered binary treesquot;) while others work on plain binary trees with no special ordering. The next
section, Section 3, shows the solution code in C/C++. Section 4 gives the background and solution code in Java. The
basic structure and recursion of the solution code is the same in both languages -- the differences are superficial.
Reading about a data structure is a fine introduction, but at some point the only way to learn is to actually try to
solve some problems starting with a blank sheet of paper. To get the most out of these problems, you should at least
attempt to solve them before looking at the solution. Even if your solution is not quite right, you will be building up
the right skills. With any pointer-based code, it's a good idea to make memory drawings of a a few simple cases to
see how the algorithm should work.
1. build123()
This is a very basic problem with a little pointer manipulation. (You can skip this problem if you are already
comfortable with pointers.) Write code that builds the following little 1-2-3 binary search tree...
2
/
1 3
Write the code in three different ways...
a: by calling newNode() three times, and using three pointer variables
b: by calling newNode() three times, and using only one pointer variable
c: by calling insert() three times passing it the root pointer to build up the tree
(In Java, write a build123() method that operates on the receiver to change it to be the 1-2-3 tree with the given
coding constraints. See Section 4.)
struct node* build123() {
2. size()
http://cslibrary.stanford.edu/110/
BinaryTrees.html
6. Binary Trees Page: 6
This problem demonstrates simple binary tree traversal. Given a binary tree, count the number of nodes in the tree.
int size(struct node* node) {
3. maxDepth()
Given a binary tree, compute its quot;maxDepthquot; -- the number of nodes along the longest path from the root node down
to the farthest leaf node. The maxDepth of the empty tree is 0, the maxDepth of the tree on the first page is 3.
int maxDepth(struct node* node) {
4. minValue()
Given a non-empty binary search tree (an ordered binary tree), return the minimum data value found in that tree.
Note that it is not necessary to search the entire tree. A maxValue() function is structurally very similar to this
function. This can be solved with recursion or with a simple while loop.
int minValue(struct node* node) {
5. printTree()
Given a binary search tree (aka an quot;ordered binary treequot;), iterate over the nodes to print them out in increasing
order. So the tree...
4
/
2 5
/
1 3
Produces the output quot;1 2 3 4 5quot;. This is known as an quot;inorderquot; traversal of the tree.
Hint: For each node, the strategy is: recur left, print the node data, recur right.
void printTree(struct node* node) {
6. printPostorder()
Given a binary tree, print out the nodes of the tree according to a bottom-up quot;postorderquot; traversal -- both subtrees of
a node are printed out completely before the node itself is printed, and each left subtree is printed before the right
subtree. So the tree...
4
/
2 5
/
1 3
Produces the output quot;1 3 2 5 4quot;. The description is complex, but the code is simple. This is the sort of bottom-up
traversal that would be used, for example, to evaluate an expression tree where a node is an operation like '+' and
its subtrees are, recursively, the two subexpressions for the '+'.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
7. Binary Trees Page: 7
void printPostorder(struct node* node) {
7. hasPathSum()
We'll define a quot;root-to-leaf pathquot; to be a sequence of nodes in a tree starting with the root node and proceeding
downward to a leaf (a node with no children). We'll say that an empty tree contains no root-to-leaf paths. So for
example, the following tree has exactly four root-to-leaf paths:
5
/
4 8
/ /
11 13 4
/
7 2 1
Root-to-leaf paths:
path 1: 5 4 11 7
path 2: 5 4 11 2
path 3: 5 8 13
path 4: 5 8 4 1
For this problem, we will be concerned with the sum of the values of such a path -- for example, the sum of the
values on the 5-4-11-7 path is 5 + 4 + 11 + 7 = 27.
Given a binary tree and a sum, return true if the tree has a root-to-leaf path such that adding up all the values
along the path equals the given sum. Return false if no such path can be found. (Thanks to Owen Astrachan for
suggesting this problem.)
int hasPathSum(struct node* node, int sum) {
8. printPaths()
Given a binary tree, print out all of its root-to-leaf paths as defined above. This problem is a little harder than it
looks, since the quot;path so farquot; needs to be communicated between the recursive calls. Hint: In C, C++, and Java,
probably the best solution is to create a recursive helper function printPathsRecur(node, int path[], int pathLen),
where the path array communicates the sequence of nodes that led up to the current call. Alternately, the problem
may be solved bottom-up, with each node returning its list of paths. This strategy works quite nicely in Lisp, since
it can exploit the built in list and mapping primitives. (Thanks to Matthias Felleisen for suggesting this problem.)
Given a binary tree, print out all of its root-to-leaf paths, one per line.
void printPaths(struct node* node) {
9. mirror()
Change a tree so that the roles of the left and right pointers are swapped at every node.
So the tree...
4
/
2 5
/
http://cslibrary.stanford.edu/110/
BinaryTrees.html
8. Binary Trees Page: 8
1 3
is changed to...
4
/
5 2
/
3 1
The solution is short, but very recursive. As it happens, this can be accomplished without changing the root node
pointer, so the return-the-new-root construct is not necessary. Alternately, if you do not want to change the tree
nodes, you may construct and return a new mirror tree based on the original tree.
void mirror(struct node* node) {
10. doubleTree()
For each node in a binary search tree, create a new duplicate node, and insert the duplicate as the left child of the
original node. The resulting tree should still be a binary search tree.
So the tree...
2
/
1 3
is changed to...
2
/
2 3
/ /
1 3
/
1
As with the previous problem, this can be accomplished without changing the root node pointer.
void doubleTree(struct node* node) {
11. sameTree()
Given two binary trees, return true if they are structurally identical -- they are made of nodes with the same values
arranged in the same way. (Thanks to Julie Zelenski for suggesting this problem.)
int sameTree(struct node* a, struct node* b) {
12. countTrees()
This is not a binary tree programming problem in the ordinary sense -- it's more of a math/combinatorics recursion
problem that happens to use binary trees. (Thanks to Jerry Cain for suggesting this problem.)
Suppose you are building an N node binary search tree with the values 1..N. How many structurally different
binary search trees are there that store those values? Write a recursive function that, given the number of distinct
values, computes the number of structurally unique binary search trees that store those values. For example,
http://cslibrary.stanford.edu/110/
BinaryTrees.html
9. Binary Trees Page: 9
countTrees(4) should return 14, since there are 14 structurally unique binary search trees that store 1, 2, 3, and 4. The
base case is easy, and the recursion is short but dense. Your code should not construct any actual trees; it's just a
counting problem.
int countTrees(int numKeys) {
Binary Search Tree Checking (for problems 13 and 14)
This background is used by the next two problems: Given a plain binary tree, examine the tree to determine if it
meets the requirement to be a binary search tree. To be a binary search tree, for every node, all of the nodes in its
left tree must be <= the node, and all of the nodes in its right subtree must be > the node. Consider the following four
examples...
a. 5 -> TRUE
/
2 7
b. 5 -> FALSE, because the 6 is not ok to the left of the 5
/
6 7
c. 5 -> TRUE
/
2 7
/
1
d. 5 -> FALSE, the 6 is ok with the 2, but the 6 is not ok with the 5
/
2 7
/
1 6
For the first two cases, the right answer can be seen just by comparing each node to the two nodes immediately
below it. However, the fourth case shows how checking the BST quality may depend on nodes which are several
layers apart -- the 5 and the 6 in that case.
13 isBST() -- version 1
Suppose you have helper functions minValue() and maxValue() that return the min or max int value from a
non-empty tree (see problem 3 above). Write an isBST() function that returns true if a tree is a binary search tree
and false otherwise. Use the helper functions, and don't forget to check every node in the tree. It's ok if your
solution is not very efficient. (Thanks to Owen Astrachan for the idea of having this problem, and comparing it to
problem 14)
Returns true if a binary tree is a binary search tree.
int isBST(struct node* node) {
14. isBST() -- version 2
http://cslibrary.stanford.edu/110/
BinaryTrees.html
10. Binary Trees Page: 10
Version 1 above runs slowly since it traverses over some parts of the tree many times. A better solution looks at each
node only once. The trick is to write a utility helper function isBSTRecur(struct node* node, int min, int max) that
traverses down the tree keeping track of the narrowing min and max allowed values as it goes, looking at each node
only once. The initial values for min and max should be INT_MIN and INT_MAX -- they narrow from there.
/*
Returns true if the given tree is a binary search tree
(efficient version).
*/
int isBST2(struct node* node) {
return(isBSTRecur(node, INT_MIN, INT_MAX));
}
/*
Returns true if the given tree is a BST and its
values are >= min and <= max.
*/
int isBSTRecur(struct node* node, int min, int max) {
15. Tree-List
The Tree-List problem is one of the greatest recursive pointer problems ever devised, and it happens to use binary
trees as well. CLibarary #109 http://cslibrary.stanford.edu/109/ works through the Tree-List problem in detail
and includes solution code in C and Java. The problem requires an understanding of binary trees, linked lists,
recursion, and pointers. It's a great problem, but it's complex.
Section 3 -- C/C++ Solutions
Make an attempt to solve each problem before looking at the solution -- it's the best way to learn.
1. Build123() Solution (C/C++)
// call newNode() three times
struct node* build123a() {
struct node* root = newNode(2);
struct node* lChild = newNode(1);
struct node* rChild = newNode(3);
root->left = lChild;
root->right= rChild;
return(root);
}
// call newNode() three times, and use only one local variable
struct node* build123b() {
struct node* root = newNode(2);
root->left = newNode(1);
root->right = newNode(3);
return(root);
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html
11. Binary Trees Page: 11
/*
Build 123 by calling insert() three times.
Note that the '2' must be inserted first.
*/
struct node* build123c() {
struct node* root = NULL;
root = insert(root, 2);
root = insert(root, 1);
root = insert(root, 3);
return(root);
}
2. size() Solution (C/C++)
/*
Compute the number of nodes in a tree.
*/
int size(struct node* node) {
if (node==NULL) {
return(0);
} else {
return(size(node->left) + 1 + size(node->right));
}
}
3. maxDepth() Solution (C/C++)
/*
Compute the quot;maxDepthquot; of a tree -- the number of nodes along
the longest path from the root node down to the farthest leaf node.
*/
int maxDepth(struct node* node) {
if (node==NULL) {
return(0);
}
else {
// compute the depth of each subtree
int lDepth = maxDepth(node->left);
int rDepth = maxDepth(node->right);
// use the larger one
if (lDepth > rDepth) return(lDepth+1);
else return(rDepth+1);
}
}
4. minValue() Solution (C/C++)
/*
Given a non-empty binary search tree,
return the minimum data value found in that tree.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
12. Binary Trees Page: 12
Note that the entire tree does not need to be searched.
*/
int minValue(struct node* node) {
struct node* current = node;
// loop down to find the leftmost leaf
while (current->left != NULL) {
current = current->left;
}
return(current->data);
}
5. printTree() Solution (C/C++)
/*
Given a binary search tree, print out
its data elements in increasing
sorted order.
*/
void printTree(struct node* node) {
if (node == NULL) return;
printTree(node->left);
printf(quot;%d quot;, node->data);
printTree(node->right);
}
6. printPostorder() Solution (C/C++)
/*
Given a binary tree, print its
nodes according to the quot;bottom-upquot;
postorder traversal.
*/
void printPostorder(struct node* node) {
if (node == NULL) return;
// first recur on both subtrees
printTree(node->left);
printTree(node->right);
// then deal with the node
printf(quot;%d quot;, node->data);
}
7. hasPathSum() Solution (C/C++)
/*
Given a tree and a sum, return true if there is a path from the root
down to a leaf, such that adding up all the values along the path
equals the given sum.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
13. Binary Trees Page: 13
Strategy: subtract the node value from the sum when recurring down,
and check to see if the sum is 0 when you run out of tree.
*/
int hasPathSum(struct node* node, int sum) {
// return true if we run out of tree and sum==0
if (node == NULL) {
return(sum == 0);
}
else {
// otherwise check both subtrees
int subSum = sum - node->data;
return(hasPathSum(node->left, subSum) ||
hasPathSum(node->right, subSum));
}
}
8. printPaths() Solution (C/C++)
/*
Given a binary tree, print out all of its root-to-leaf
paths, one per line. Uses a recursive helper to do the work.
*/
void printPaths(struct node* node) {
int path[1000];
printPathsRecur(node, path, 0);
}
/*
Recursive helper function -- given a node, and an array containing
the path from the root node up to but not including this node,
print out all the root-leaf paths.
*/
void printPathsRecur(struct node* node, int path[], int pathLen) {
if (node==NULL) return;
// append this node to the path array
path[pathLen] = node->data;
pathLen++;
// it's a leaf, so print the path that led to here
if (node->left==NULL && node->right==NULL) {
printArray(path, pathLen);
}
else {
// otherwise try both subtrees
printPathsRecur(node->left, path, pathLen);
printPathsRecur(node->right, path, pathLen);
}
}
// Utility that prints out an array on a line.
void printArray(int ints[], int len) {
int i;
for (i=0; i<len; i++) {
http://cslibrary.stanford.edu/110/
BinaryTrees.html
14. Binary Trees Page: 14
printf(quot;%d quot;, ints[i]);
}
printf(quot;nquot;);
}
9. mirror() Solution (C/C++)
/*
Change a tree so that the roles of the
left and right pointers are swapped at every node.
So the tree...
4
/
2 5
/
1 3
is changed to...
4
/
5 2
/
3 1
*/
void mirror(struct node* node) {
if (node==NULL) {
return;
}
else {
struct node* temp;
// do the subtrees
mirror(node->left);
mirror(node->right);
// swap the pointers in this node
temp = node->left;
node->left = node->right;
node->right = temp;
}
}
10. doubleTree() Solution (C/C++)
/*
For each node in a binary search tree,
create a new duplicate node, and insert
the duplicate as the left child of the original node.
The resulting tree should still be a binary search tree.
So the tree...
2
/
http://cslibrary.stanford.edu/110/
BinaryTrees.html
15. Binary Trees Page: 15
1 3
Is changed to...
2
/
2 3
/ /
1 3
/
1
*/
void doubleTree(struct node* node) {
struct node* oldLeft;
if (node==NULL) return;
// do the subtrees
doubleTree(node->left);
doubleTree(node->right);
// duplicate this node to its left
oldLeft = node->left;
node->left = newNode(node->data);
node->left->left = oldLeft;
}
11. sameTree() Solution (C/C++)
/*
Given two trees, return true if they are
structurally identical.
*/
int sameTree(struct node* a, struct node* b) {
// 1. both empty -> true
if (a==NULL && b==NULL) return(true);
// 2. both non-empty -> compare them
else if (a!=NULL && b!=NULL) {
return(
a->data == b->data &&
sameTree(a->left, b->left) &&
sameTree(a->right, b->right)
);
}
// 3. one empty, one not -> false
else return(false);
}
12. countTrees() Solution (C/C++)
/*
For the key values 1...numKeys, how many structurally unique
http://cslibrary.stanford.edu/110/
BinaryTrees.html
16. Binary Trees Page: 16
binary search trees are possible that store those keys.
Strategy: consider that each value could be the root.
Recursively find the size of the left and right subtrees.
*/
int countTrees(int numKeys) {
if (numKeys <=1) {
return(1);
}
else {
// there will be one value at the root, with whatever remains
// on the left and right each forming their own subtrees.
// Iterate through all the values that could be the root...
int sum = 0;
int left, right, root;
for (root=1; root<=numKeys; root++) {
left = countTrees(root - 1);
right = countTrees(numKeys - root);
// number of possible trees with this root == left*right
sum += left*right;
}
return(sum);
}
}
13. isBST1() Solution (C/C++)
/*
Returns true if a binary tree is a binary search tree.
*/
int isBST(struct node* node) {
if (node==NULL) return(true);
// false if the min of the left is > than us
if (node->left!=NULL && minValue(node->left) > node->data)
return(false);
// false if the max of the right is <= than us
if (node->right!=NULL && maxValue(node->right) <= node->data)
return(false);
// false if, recursively, the left or right is not a BST
if (!isBST(node->left) || !isBST(node->right))
return(false);
// passing all that, it's a BST
return(true);
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html
17. Binary Trees Page: 17
14. isBST2() Solution (C/C++)
/*
Returns true if the given tree is a binary search tree
(efficient version).
*/
int isBST2(struct node* node) {
return(isBSTUtil(node, INT_MIN, INT_MAX));
}
/*
Returns true if the given tree is a BST and its
values are >= min and <= max.
*/
int isBSTUtil(struct node* node, int min, int max) {
if (node==NULL) return(true);
// false if this node violates the min/max constraint
if (node->data<min || node->data>max) return(false);
// otherwise check the subtrees recursively,
// tightening the min or max constraint
return
isBSTUtil(node->left, min, node->data) &&
isBSTUtil(node->right, node->data+1, max)
);
}
15. TreeList Solution (C/C++)
The solution code in C and Java to the great Tree-List recursion problem is in CSLibrary #109
http://cslibrary.stanford.edu/109/
Section 4 -- Java Binary Trees and Solutions
In Java, the key points in the recursion are exactly the same as in C or C++. In fact, I created the Java solutions by
just copying the C solutions, and then making the syntactic changes. The recursion is the same, however the outer
structure is slightly different.
In Java, we will have a BinaryTree object that contains a single root pointer. The root pointer points to an internal
Node class that behaves just like the node struct in the C/C++ version. The Node class is private -- it is used only
for internal storage inside the BinaryTree and is not exposed to clients. With this OOP structure, almost every
operation has two methods: a one-line method on the BinaryTree that starts the computation, and a recursive
method that works on the Node objects. For the lookup() operation, there is a BinaryTree.lookup() method that
the client uses to start a lookup operation. Internal to the BinaryTree class, there is a private recursive
lookup(Node) method that implements the recursion down the Node structure. This second, private recursive
method is basically the same as the recursive C/C++ functions above -- it takes a Node argument and uses recursion
to iterate over the pointer structure.
Java Binary Tree Structure
To get started, here are the basic definitions for the Java BinaryTree class, and the lookup() and insert() methods
as examples...
http://cslibrary.stanford.edu/110/
BinaryTrees.html
18. Binary Trees Page: 18
// BinaryTree.java
public class BinaryTree {
// Root node pointer. Will be null for an empty tree.
private Node root;
/*
--Node--
The binary tree is built using this nested node class.
Each node stores one data element, and has left and right
sub-tree pointer which may be null.
The node is a quot;dumbquot; nested class -- we just use it for
storage; it does not have any methods.
*/
private static class Node {
Node left;
Node right;
int data;
Node(int newData) {
left = null;
right = null;
data = newData;
}
}
/**
Creates an empty binary tree -- a null root pointer.
*/
public void BinaryTree() {
root = null;
}
/**
Returns true if the given target is in the binary tree.
Uses a recursive helper.
*/
public boolean lookup(int data) {
return(lookup(root, data));
}
/**
Recursive lookup -- given a node, recur
down searching for the given data.
*/
private boolean lookup(Node node, int data) {
if (node==null) {
return(false);
}
if (data==node.data) {
return(true);
}
else if (data<node.data) {
http://cslibrary.stanford.edu/110/
BinaryTrees.html
19. Binary Trees Page: 19
return(lookup(node.left, data));
}
else {
return(lookup(node.right, data));
}
}
/**
Inserts the given data into the binary tree.
Uses a recursive helper.
*/
public void insert(int data) {
root = insert(root, data);
}
/**
Recursive insert -- given a node pointer, recur down and
insert the given data into the tree. Returns the new
node pointer (the standard way to communicate
a changed pointer back to the caller).
*/
private Node insert(Node node, int data) {
if (node==null) {
node = new Node(data);
}
else {
if (data <= node.data) {
node.left = insert(node.left, data);
}
else {
node.right = insert(node.right, data);
}
}
return(node); // in any case, return the new pointer to the caller
}
OOP Style vs. Recursive Style
From the client point of view, the BinaryTree class demonstrates good OOP style -- it encapsulates the binary tree
state, and the client sends messages like lookup() and insert() to operate on that state. Internally, the Node class
and the recursive methods do not demonstrate OOP style. The recursive methods like insert(Node) and lookup
(Node, int) basically look like recursive functions in any language. In particular, they do not operate against a
quot;receiverquot; in any special way. Instead, the recursive methods operate on the arguments that are passed in which is
the classical way to write recursion. My sense is that the OOP style and the recursive style do not be combined
nicely for binary trees, so I have left them separate. Merging the two styles would be especially awkward for the
quot;emptyquot; tree (null) case, since you can't send a message to the null pointer. It's possible to get around that by having
a special object to represent the null tree, but that seems like a distraction to me. I prefer to keep the recursive
methods simple, and use different examples to teach OOP.
Java Solutions
Here are the Java solutions to the 14 binary tree problems. Most of the solutions use two methods:a one-line OOP
http://cslibrary.stanford.edu/110/
BinaryTrees.html
20. Binary Trees Page: 20
method that starts the computation, and a recursive method that does the real operation. Make an attempt to
solve each problem before looking at the solution -- it's the best way to learn.
1. Build123() Solution (Java)
/**
Build 123 using three pointer variables.
*/
public void build123a() {
root = new Node(2);
Node lChild = new Node(1);
Node rChild = new Node(3);
root.left = lChild;
root.right= rChild;
}
/**
Build 123 using only one pointer variable.
*/
public void build123b() {
root = new Node(2);
root.left = new Node(1);
root.right = new Node(3);
}
/**
Build 123 by calling insert() three times.
Note that the '2' must be inserted first.
*/
public void build123c() {
root = null;
root = insert(root, 2);
root = insert(root, 1);
root = insert(root, 3);
}
2. size() Solution (Java)
/**
Returns the number of nodes in the tree.
Uses a recursive helper that recurs
down the tree and counts the nodes.
*/
public int size() {
return(size(root));
}
private int size(Node node) {
if (node == null) return(0);
else {
return(size(node.left) + 1 + size(node.right));
}
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html
21. Binary Trees Page: 21
3. maxDepth() Solution (Java)
/**
Returns the max root-to-leaf depth of the tree.
Uses a recursive helper that recurs down to find
the max depth.
*/
public int maxDepth() {
return(maxDepth(root));
}
private int maxDepth(Node node) {
if (node==null) {
return(0);
}
else {
int lDepth = maxDepth(node.left);
int rDepth = maxDepth(node.right);
// use the larger + 1
return(Math.max(lDepth, rDepth) + 1);
}
}
4. minValue() Solution (Java)
/**
Returns the min value in a non-empty binary search tree.
Uses a helper method that iterates to the left to find
the min value.
*/
public int minValue() {
return( minValue(root) );
}
/**
Finds the min value in a non-empty binary search tree.
*/
private int minValue(Node node) {
Node current = node;
while (current.left != null) {
current = current.left;
}
return(current.data);
}
5. printTree() Solution (Java)
/**
Prints the node values in the quot;inorderquot; order.
Uses a recursive helper to do the traversal.
http://cslibrary.stanford.edu/110/
BinaryTrees.html
22. Binary Trees Page: 22
*/
public void printTree() {
printTree(root);
System.out.println();
}
private void printTree(Node node) {
if (node == null) return;
// left, node itself, right
printTree(node.left);
System.out.print(node.data + quot; quot;);
printTree(node.right);
}
6. printPostorder() Solution (Java)
/**
Prints the node values in the quot;postorderquot; order.
Uses a recursive helper to do the traversal.
*/
public void printPostorder() {
printPostorder(root);
System.out.println();
}
public void printPostorder(Node node) {
if (node == null) return;
// first recur on both subtrees
printPostorder(node.left);
printPostorder(node.right);
// then deal with the node
System.out.print(node.data + quot; quot;);
}
7. hasPathSum() Solution (Java)
/**
Given a tree and a sum, returns true if there is a path from the root
down to a leaf, such that adding up all the values along the path
equals the given sum.
Strategy: subtract the node value from the sum when recurring down,
and check to see if the sum is 0 when you run out of tree.
*/
public boolean hasPathSum(int sum) {
return( hasPathSum(root, sum) );
}
boolean hasPathSum(Node node, int sum) {
// return true if we run out of tree and sum==0
if (node == null) {
http://cslibrary.stanford.edu/110/
BinaryTrees.html
23. Binary Trees Page: 23
return(sum == 0);
}
else {
// otherwise check both subtrees
int subSum = sum - node.data;
return(hasPathSum(node.left, subSum) || hasPathSum(node.right, subSum));
}
}
8. printPaths() Solution (Java)
/**
Given a binary tree, prints out all of its root-to-leaf
paths, one per line. Uses a recursive helper to do the work.
*/
public void printPaths() {
int[] path = new int[1000];
printPaths(root, path, 0);
}
/**
Recursive printPaths helper -- given a node, and an array containing
the path from the root node up to but not including this node,
prints out all the root-leaf paths.
*/
private void printPaths(Node node, int[] path, int pathLen) {
if (node==null) return;
// append this node to the path array
path[pathLen] = node.data;
pathLen++;
// it's a leaf, so print the path that led to here
if (node.left==null && node.right==null) {
printArray(path, pathLen);
}
else {
// otherwise try both subtrees
printPaths(node.left, path, pathLen);
printPaths(node.right, path, pathLen);
}
}
/**
Utility that prints ints from an array on one line.
*/
private void printArray(int[] ints, int len) {
int i;
for (i=0; i<len; i++) {
System.out.print(ints[i] + quot; quot;);
}
System.out.println();
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html
24. Binary Trees Page: 24
9. mirror() Solution (Java)
/**
Changes the tree into its mirror image.
So the tree...
4
/
2 5
/
1 3
is changed to...
4
/
5 2
/
3 1
Uses a recursive helper that recurs over the tree,
swapping the left/right pointers.
*/
public void mirror() {
mirror(root);
}
private void mirror(Node node) {
if (node != null) {
// do the sub-trees
mirror(node.left);
mirror(node.right);
// swap the left/right pointers
Node temp = node.left;
node.left = node.right;
node.right = temp;
}
}
10. doubleTree() Solution (Java)
/**
Changes the tree by inserting a duplicate node
on each nodes's .left.
So the tree...
2
/
1 3
Is changed to...
2
http://cslibrary.stanford.edu/110/
BinaryTrees.html
25. Binary Trees Page: 25
/
2 3
/ /
1 3
/
1
Uses a recursive helper to recur over the tree
and insert the duplicates.
*/
public void doubleTree() {
doubleTree(root);
}
private void doubleTree(Node node) {
Node oldLeft;
if (node == null) return;
// do the subtrees
doubleTree(node.left);
doubleTree(node.right);
// duplicate this node to its left
oldLeft = node.left;
node.left = new Node(node.data);
node.left.left = oldLeft;
}
11. sameTree() Solution (Java)
/*
Compares the receiver to another tree to
see if they are structurally identical.
*/
public boolean sameTree(BinaryTree other) {
return( sameTree(root, other.root) );
}
/**
Recursive helper -- recurs down two trees in parallel,
checking to see if they are identical.
*/
boolean sameTree(Node a, Node b) {
// 1. both empty -> true
if (a==null && b==null) return(true);
// 2. both non-empty -> compare them
else if (a!=null && b!=null) {
return(
a.data == b.data &&
sameTree(a.left, b.left) &&
sameTree(a.right, b.right)
);
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html
26. Binary Trees Page: 26
// 3. one empty, one not -> false
else return(false);
}
12. countTrees() Solution (Java)
/**
For the key values 1...numKeys, how many structurally unique
binary search trees are possible that store those keys?
Strategy: consider that each value could be the root.
Recursively find the size of the left and right subtrees.
*/
public static int countTrees(int numKeys) {
if (numKeys <=1) {
return(1);
}
else {
// there will be one value at the root, with whatever remains
// on the left and right each forming their own subtrees.
// Iterate through all the values that could be the root...
int sum = 0;
int left, right, root;
for (root=1; root<=numKeys; root++) {
left = countTrees(root-1);
right = countTrees(numKeys - root);
// number of possible trees with this root == left*right
sum += left*right;
}
return(sum);
}
}
13. isBST1() Solution (Java)
/**
Tests if a tree meets the conditions to be a
binary search tree (BST).
*/
public boolean isBST() {
return(isBST(root));
}
/**
Recursive helper -- checks if a tree is a BST
using minValue() and maxValue() (not efficient).
*/
private boolean isBST(Node node) {
if (node==null) return(true);
// do the subtrees contain values that do not
http://cslibrary.stanford.edu/110/
BinaryTrees.html
27. Binary Trees Page: 27
// agree with the node?
if (node.left!=null && maxValue(node.left) > node.data) return(false);
if (node.right!=null && minValue(node.right) <= node.data) return(false);
// check that the subtrees themselves are ok
return( isBST(node.left) && isBST(node.right) );
}
14. isBST2() Solution (Java)
/**
Tests if a tree meets the conditions to be a
binary search tree (BST). Uses the efficient
recursive helper.
*/
public boolean isBST2() {
return( isBST2(root, Integer.MIN_VALUE, Integer.MAX_VALUE) );
}
/**
Efficient BST helper -- Given a node, and min and max values,
recurs down the tree to verify that it is a BST, and that all
its nodes are within the min..max range. Works in O(n) time --
visits each node only once.
*/
private boolean isBST2(Node node, int min, int max) {
if (node==null) {
return(true);
}
else {
// left should be in range min...node.data
boolean leftOk = isBST2(node.left, min, node.data);
// if the left is not ok, bail out
if (!leftOk) return(false);
// right should be in range node.data+1..max
boolean rightOk = isBST2(node.right, node.data+1, max);
return(rightOk);
}
}
http://cslibrary.stanford.edu/110/
BinaryTrees.html