Title: Advanced Pointers and Structures
1Advanced Pointers and Structures
- Pointers in structures
- Memory allocation
- Linked Lists
- Stacks and queues
- Trees
- Binary tree example
2Structs which contain themselves
- Sometimes programmers want structs in C to
contain themselves. - For example, we might design an electronic
dictionary which has a struct for each word and
we might want to refer to synonyms which are also
word structures.
word1run synonym1 synonym2
word3 jog synonym1 synonym2
word2 sprint synonym1 synonym2
3How structs can contain themselves
- Clearly a struct cannot literally contain itself.
- But it can contain a pointer to the same type of
struct
struct silly_struct / This doesn't work /
struct silly_struct s1
struct good_struct / This does work /
struct good_struct s2
4Memory allocation
- How to allocate memory dynamically?
- void malloc(unsigned int)
- Example
- char str
- str malloc(80)
- Now str can hold up to 80 Bytes.
-
5Freeing memory
- To free memory that was allocated using malloc we
use free function. - free returns the memory pointed by a given
pointer to the OS. - free(pointer)
- pointer NULL
6The linked list - a common use of structs which
contain themselves
- Imagine we are reading lines from a file but
don't know how many lines will be read. - We need a structure which can extend itself.
This is known as a linked list. By passing the
value of the head of the list to a function we
can pass ALL the information.
7How to set up a linked list
typedef struct list_item information in
each item struct list_item nextptr
LIST_ITEM
This structure (where information is what you
want each "node" of your linked list to contain).
It is important that the nextptr of the last bit
of the list contains NULL so that you know when
to stop.
8Example -- Address book
typedef struct list char nameMAXLEN
char addressMAXLEN char phoneMAXLEN
struct list next ADDRESS ADDRESS
myabook NULL / Set the head of the list /
9Linked list concepts
Adding an item to the middle of the list
head of list
NULL
move this link
new item points at next item
Deleting an item from the middle of the list
move this link
head of list
NULL
delete this node
10Stacks and Queues
- Stacks use push and pop
- Push add a node at the head of a linked list.
- Pop remove the head node
- Queues
- Adding nodes at the head of the list
- Removing nodes at the end of a list
- So we need 2 pointers, one for the head and one
for the tail.
11Tree
- A tree is a method for data (for example a
dictionary of words) where we wish to easily be
able to add items and find items - Each element in the tree can lead to two (or
more) further elements.
struct TreeNode ... Data part TreeNode
child1 TreeNode child2 ...
12Binary Tree Structure Example
- A binary tree is a data structure
- The basic data structure is a node which
includes - The data contained in that node
- Pointers to two children nodes (left and right)
- 2 pointers binary
- Left node pointer points to a node with data that
is less than the current node - Right node pointer points to a node with data
that is greater than the current node - All nodes to the left contain data less
- All nodes to the right contain data greater
- A leaf node is a node with no children
13Binary Tree Adding a node
- Simply add a leaf to the tree.
- Add 20
10
10
8
30
8
30
40
5
20
40
5
14Binary Tree
10
8
30
20
5
40
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Add 15?
15Binary Tree
10
8
30
20
5
40
15
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Add the value 9?
16Insert
10
8
30
9
20
5
40
15
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Add 25?
17Insert
10
8
30
9
20
5
40
15
25
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Remove 5?
18Removing a node from a binary tree
- Node has no children
- Simply remove it from tree
- Node has one child
- Remove the node and replace it with its child
- Node has two children
- Replace the nodes value with (2 options)
- the left-most value of the right tree.
- the right-most value of the left tree.
19Remove Leaf
10
8
30
9
20
5
40
15
25
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Remove 8?
20Remove node with one child
10
9
30
20
40
15
25
- All nodes on the left are less than 10 and all
on the right are greater than 10 - Remove 20?
21Remove node with two children
10
9
30
25
40
15
25
- Replace value with left-most value of the right
tree - All nodes on the left are less than 10 and all
on the right are greater than 10 - Remove 10?
22Remove node with two children
15
9
30
25
40
15
- Replace value with left-most value of the right
tree - All nodes on the left are less than 15 and all
on the right are greater than 15
23The Binary Tree Node Structure
- struct BinaryTreeNode
-
- int value
- BinaryTreeNode left
- BinaryTreeNode right
24Removing a node from a binary tree
- RemoveNode(node head)
-
- if (head-gtleft null)
- node t head
- head head-gtright
- free_node(t)
- else if (head-gtright null)
- node t head
- head head-gtleft
- free_node(t)
- else
- node t head-gtright
- while(t-gtleft)
- t t-gtleft
- head-gtvalue t-gtvalue
- RemoveNode(t)
-
25The binary tree
NULL
NULL
typedef struct tree char word100
struct tree left struct tree right TREE
NULL
NULL
NULL
NULL
NULL
26Binary Tree Pros Cons
- Finding an element is O(log n)
- Adding an element is O(log n) O(1) if we
already know where to add it. - Deleting an element may be complex
- Programming complexity is higher than a linked
list (just about)
27Deleting an entire binary tree
- I think this code is elegant and worth looking at
void delete_tree (TREE ptr) if (ptr
NULL) return delete_tree(ptr-gtleft)
delete_tree(ptr-gtright) free (ptr)
We can delete the whole tree with
delete_tree(root_of_tree
)
28A binary tree example - words.c
- /
- words -- scan a file and print out a list of
words - in ASCII order.
-
- Usage
- words ltfilegt
-
/ - include ltstdio.hgt
- include ltctype.hgt
- include ltstring.hgt
- include ltstdlib.hgt
- struct node
- struct node left / tree to the
left / - struct node right / tree to the
right / - char word / word for this
tree / -
- / the top of the tree /
29- void memory_error(void)
-
- fprintf(stderr, "ErrorOut of memory\n")
- exit(8)
-
- char save_string(char string)
-
- char new_string / where we are going to
put string / - new_string malloc((unsigned)
(strlen(string) 1)) - if (new_string NULL)
- memory_error()
- strcpy(new_string, string)
- return (new_string)
-
30- void enter(struct node node, char word)
- int result / result of strcmp /
- char save_string(char ) / save a string on
the heap / -
- / If the current node is null, we have
reached the bottom - of the tree and must create a new node.
- /
- if ((node) NULL)
- / Allocate memory for a new node /
- (node) malloc(sizeof(struct node))
- if ((node) NULL) memory_error()
- / Initialize the new node /
- (node)-gtleft NULL
- (node)-gtright NULL
- (node)-gtword save_string(word)
- return
-
- / Check to see where the word goes /
31- void scan(char name)
- char word100 / word we are working on
/ - int index / index into the word /
- int ch / current character /
- FILE in_file / input file /
- in_file fopen(name, "r")
- if (in_file NULL)
- fprintf(stderr, "ErrorUnable to open
s\n", name) - exit(8)
-
- while (1)
- / scan past the whitespace /
- while (1)
- ch fgetc(in_file)
- if (isalpha(ch) (ch EOF))
- break
-
- if (ch EOF)
- break
ch fgetc(in_file) if
(!isalpha(ch)) break
wordindex ch / put a null
on the end / wordindex '\0'
enter(root, word) fclose(in_file)
32- void print_tree(struct node top)
-
- if (top NULL)
- return / short tree /
- print_tree(top-gtleft)
- printf("s\n", top-gtword)
- print_tree(top-gtright)
-
- int main(int argc, char argv)
-
- if (argc ! 2)
- fprintf(stderr, "ErrorWrong number of
parameters\n") - fprintf(stderr, " on the command
line\n") - fprintf(stderr, "Usage is\n")
- fprintf(stderr, " words 'file'\n")
- exit(8)
-