tree c and data structures baojian hua [email protected]

44
Tree C and Data Structures Baojian Hua [email protected]

Post on 21-Dec-2015

228 views

Category:

Documents


0 download

TRANSCRIPT

Tree

C and Data StructuresBaojian Hua

[email protected]

What’ s a Tree?

book

chap1 chap2 chap3

sec11 sec12 sec21

subsec111

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

What’ s a Tree?

book

chap1 chap2 chap3

sec11 sec12 sec21

subsec111

unique root

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

Examples

book

chap1 chap2

sec11 sec12 sec21

subsec111

sec22

book

chap1

sec11

subsec111

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->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?

book

chap1 chap2

sec11 sec12 sec21

subsec111

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 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” /\

Example

t

left “a” right

/\ “b” right /\ “c” /\

/\ “d” /\

t

Example

t

left “a” right

/\ “b” right /\ “c” /\

/\ “d” /\

t->l

print out “a”

Example

t

left “a” right

/\ “b” right /\ “c” /\

/\ “d” /\

t->r

t->l

print out “a”

Example

t

left “a” right

/\ “b” right /\ “c” /\

/\ “d” /\

t->r

print out “a”

print out “b”

Example

t

left “a” right

/\ “b” right /\ “c” /\

/\ “d” /\

t->l->r

t->r

print out “a”

print out “b”

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”

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