Download slides

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Tree
C and Data Structures
Baojian Hua
[email protected]
What’ s a Tree?
book
chap1
sec11
subsec111
chap2
sec12
chap3
sec21
Definition of Tree

A tree is a collection of nodes, which satisfies:




there exists a unique root node r
other nodes are classified into n (n>=0) disjoint
sets T_1, …, T_n, and every T_i is also a tree.
T_1, …, T_n are called sub-trees of r.
Moral:


Recursive definition
Sub-trees disjoint
What’ s a Tree?
unique root
book
chap1
sec11
subsec111
chap2
sec12
chap3
sec21
Terminologies
depth=0
root
book
internal
node
chap1
depth=1
chap2
chap3
degree
depth=2
node & child
parent
sec11
sec12
sec21
depth=3
siblings
subsec111
leaves
Binary Tree

A binary tree is a collection of nodes, which
satisfies:



there exists a unique root node r
other nodes are classified into n (0<=n<=2)
disjoint ordered sets T_1, …, T_n, and every set
T_i is also a binary tree.
To note:


0<=Degree(any node)<=2
the order of sub-tree is relevant
Examples
book
chap1
sec11
subsec111
book
chap1
sec11
subsec111
chap2
sec12
sec21
sec22
Properties of Binary Tree

Properties of Binary Tree

Full and Complete Binary Tree

A full binary tree is a binary tree of
depth k and 2^{k+1}-1 nodes


each node either has degree 2 (internal
nodes) or degree 0 (leaves)
A n-node complete binary tree is a tree
with nodes number of full binary tree
Abstract Data Types in C:
Interface
// in file “btree.h”
#ifndef BTREE_H
#define BTREE_H
typedef struct btreeStruct *btree;
btree newTree ();
btree newTree2 (btree left, btree right,
poly data);
void insert (btree t, poly parent, poly child,
char pos);
void preOrder (btree t, void (*visit)(poly));
void inOrder (btree t, void (*visit)(poly));
void postOrder (btree t, void (*visit)(poly));
void levelOrder (btree t, void (*visit)(poly));
#endif
Implementation
// in file “btree.c”
#include “btree.h”
struct btreeStruct
{
poly data;
btree left;
btree right;
};
t
left
data
right
Operations: “new”
// “new” creates an empty new binary tree. Just
// as the case for linked list, we may add a head
// node.
btree newTree ()
{
btree t = (btree)malloc (sizeof (*t));
t->data = NULL;
t->left = NULL;
t
t->right = NULL;
return t;
}
left
data
right
Operations: “new2”
// “newTree2” creates an tree node with fields
// properly initialized.
btree newTree2 (btree left, btree right, poly
data)
{
btree t = (btree)malloc (sizeof (*t));
t->data = data;
t->left = left;
t
t->right = right;
return t;
}
left
data
right
How to build a tree?
book
chap1
sec11
subsec111
chap2
sec12
sec21
sec22
How to build a tree?

A tree can be built in a step-by-step
way




first new an empty tree t
to insert edge (parent, child, ‘l’) or (parent,
child, ‘r’), we write a function insert
insert (t, parent, child, pos) puts the child
node at the pos field of parent node in t
if parent does not exist or has already had
a pos filed, an error occurs
Operations: “insert”
// a nearly correct version:
btree insert (btree t, poly parent, poly child,
char pos)
{
btree temp = search (t, parent);
if (pos == ‘l’) {
btree p = new2 (temp->left, NULL, child);
temp->left = p;
}
else {} // similar case for pos == ‘r’
return t;
}
Operations: “search”
btree search (btree t, poly data)
{
btree p;
if (t==NULL)
return NULL;
else if (t->data == data)
// what’s “==“ ?
return t;
else {
p = search (t->left, data);
return (p) ? (p) : (search (t->right, data));
}
}
Client Code

Create this tree:
book
chap1
sec11
subsec111
chap2
sec12
sec21
// the creation process:
t = new ();
t = insert (t, NULL, book, ‘l’);
t = insert (t, book, chap1, ‘l’);
t =insert (t, book, chap2, ‘r’);
t=insert (t, chap1, sec11, ‘l’);
t=insert (t, chap1, sec12, ‘r’);
…
…
sec22
What’s wrong with “insert”?

Many subtle conditions:





what if the search fail?
what if the arguments parent or child be NULL?
what if the pos field unequal to ‘l’ or ‘r’?
…
All these should be checked in real production
code

a style called defensive programming worth of
great recommendation
Tree Traversal
book
Traversal: a systematic way to
visit all nodes in a tree.
For instance, the visit strategies
for the right tree may be:
chap1
book, chap1, chap2
or: chap1, book, chap2
and so on.
Next, we’ll study four of them, namely: pre-order, inorder, post-order and level-order.
chap2
Pre-order Traversal

Pre-order:




first visit the root node of the tree
and then left subtree
and finally right subtree
Ex: book, chap1, chap2
chap1
book
chap2
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
“a” right
left
preOrder (t->right, visit);
}
}
“b” right
“c”
/\
/\
// try visit = printf
/\
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
“a” right
left
preOrder (t->right, visit);
}
}
“b” right
“c”
/\
/\
// try visit = printf
/\
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
“a” right
left
preOrder (t->right, visit);
}
}
“b” right
“c”
/\
/\
// print out “a”
/\
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
“a” right
left
preOrder (t->right, visit);
}
}
“b” right
“c”
/\
/\
// print out “a”
/\
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
“a” right
left
preOrder (t->right, visit);
}
}
“b” right
“c”
/\
/\
// print out “a”
// print out “b”
/\
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
preOrder (t->right, visit); left
“a” right
}
}
// print out “a”
// print out “b”
// print out “d”
/\
“b”
right
/\
/\
“c”
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
preOrder (t->right, visit); left
“a” right
}
}
// print out “a”
// print out “b”
// print out “d”
/\
“b”
right
/\
/\
“c”
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
preOrder (t->right, visit); left
“a” right
}
}
//
//
//
//
print
print
print
print
out
out
out
out
“a”
“b”
“d”
“c”
/\
“b”
right
/\
/\
“c”
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
preOrder (t->right, visit); left
“a” right
}
}
//
//
//
//
print
print
print
print
out
out
out
out
“a”
“b”
“d”
“c”
/\
“b”
right
/\
/\
“c”
“d”
/\
/\
Pre-order Traversal
void preOrder (btree t, void (*visit)(poly))
{
t
if (t) {
visit (t->data);
preOrder (t->left, visit);
preOrder (t->right, visit); left
“a” right
}
}
//
//
//
//
print
print
print
print
out
out
out
out
“a”
“b”
“d”
“c”
/\
“b”
right
/\
/\
“c”
“d”
/\
/\
Moral

preOrder is a recursive algorithm:



defined on recursively defined data structures
system (machine) keeps a stack to control the
recursive order
Generally, recursion are more elegant, easyto-write and easy-to-reason than
corresponding iterative ones


A powerful programming idiom to recommend
Some languages even encourage this by removing
“while” and “for” completely
Level-order Traversal
void levelOrder (btree t, void (*visit)(poly))
{
queue q = newQueue ();
if (t)
enQueue (q, t);
while (!queueIsEmpty(q)) {
btree temp = deQueue (q);
visit (temp->data);
if (temp->left)
enQueue (q, temp->left);
if (temp->right)
enQueue (q, temp->right);
}
return;
}
Example
t
left
/\
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t
left
/\
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->l
left
/\
print out “a”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->r
t->l
left
/\
print out “a”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->r
left
/\
print out “a”
print out “b”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->l->r
t->r
left
/\
print out “a”
print out “b”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->l->r
left
/\
print out “a”
print out “b”
print out “c”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
t->l->r
left
/\
print out “a”
print out “b”
print out “c”
“b”
right
/\
“a”
right
/\
“c”
“d”
/\
/\
Example
t
left
/\
“b”
print out “a”
/\
print out “b”
print out “c”
right
print out “d”
“a”
right
/\
“c”
“d”
/\
/\
Summary

Tree is a non-linear data structure



every element has 0, 1 or 2 successors
structure could be inductively defined
Operations could also be inductive
defined

recursive functions
Related documents