tree c and data structures baojian hua [email protected]
Post on 21-Dec-2015
228 views
TRANSCRIPT
Definition of Tree A tree is a collection of nodes, which satisfie
s: there exists a unique root node r other nodes are classified into n (n>=0) disjoint s
ets 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
Terminologies
book
chap1 chap2 chap3
sec11 sec12 sec21
subsec111
node
degree
leaves
root
internal node
parent & child
siblings
depth=1
depth=0
depth=2
depth=3
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) disjoi
nt 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
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->right = NULL;
return t;}
t
left data right
Operations: “new2”// “newTree2” creates an tree node with fields // properly initialized.btree newTree2 (btree left, btree right, poly dat
a){ btree t = (btree)malloc (sizeof (*t)); t->data = data; t->left = left; t->right = right;
return t;}
t
left data right
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 chap2
sec11 sec12 sec21
subsec111
sec22
// 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’);……
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
chap1 chap2
Traversal: a systematic way to visit all nodes in a tree.
For instance, the visit strategies for the right tree may be:
book, chap1, chap2
or: chap1, book, chap2
and so on.Next, we’ll study four of them, namely: pre-order, in-order, post-order and level-order.
Pre-order Traversal
Pre-order: first visit the root node of the tree and then left subtree and finally right subtree
Ex: book, chap1, chap2book
chap1 chap2
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// try visit = printf
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// try visit = printf
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”// print out “d”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”// print out “d”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”// print out “d”// print out “c”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”// print out “d”// print out “c”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Pre-order Traversalvoid preOrder (btree t, void (*visit)(poly)){ if (t) { visit (t->data); preOrder (t->left, visit); preOrder (t->right, visit); }}
// print out “a”// print out “b”// print out “d”// print out “c”
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
Moral preOrder is a recursive algorithm:
defined on recursively defined data structures system (machine) keeps a stack to control the re
cursive order Generally, recursion are more elegant, eas
y-to-write and easy-to-reason than corresponding iterative ones A powerful programming idiom to recommend Some languages even encourage this by removi
ng “while” and “for” completely
Level-order Traversalvoid 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 “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
t->l->r
print out “a”
print out “b”
print out “c”
Example
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\
t->l->r
print out “a”
print out “b”
print out “c”
Example
t
left “a” right
/\ “b” right /\ “c” /\
/\ “d” /\print out “a”
print out “b”
print out “c” print out “d”