-
Notifications
You must be signed in to change notification settings - Fork 0
/
Heap.java
171 lines (151 loc) · 4.71 KB
/
Heap.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
/*
Abstract class that contains the foundation for the
min and max heap classes. The implemented methods are
the ones shared between min and max heaps and the stubs
are methods with differing functionality
*/
import java.util.ArrayList;
public abstract class Heap {
// instance variables for heap data structure
protected Node<Student> root;
protected Node<Student> lastInserted;
protected int position;
// default constructor
public Heap() {
position = 1;
root = null;
lastInserted = null;
}
// heapify stub method
public abstract void heapify(Node<Student> n);
// reverse heapify stub method
public abstract void reverseHeapify(Node<Student> node);
// sorting a list of students using heap sort
public ArrayList<Student> heapSort(ArrayList<Student> list) {
// inserting list into heap
for (int i = 0; i < list.size(); i++) {
insert(list.get(i));
}
ArrayList<Student> sorted = new ArrayList<Student>();
for (int i = 0; i < list.size() - 2; i++) {
swapData(root, lastInserted); // swap top and bottom of heap
// get parent of last inserted node
Node<Student> parentLI = getParentNodeDelete(position - 1);
// store the min or max and delete it
if ((position - 1) % 2 == 0) { // if that position is even
sorted.add(parentLI.getLeft().getData());
parentLI.setLeft(null);
Node<Student> newParentLI = getParentNodeDelete(position - 2);
lastInserted = newParentLI.getRight();
} else { // if that position is odd
sorted.add(parentLI.getRight().getData());
parentLI.setRight(null);
lastInserted = parentLI.getLeft();
}
// go from top to bottom swapping
reverseHeapify(root);
position--;
}
sorted.add(root.getData()); // add root
// add second if there
if (list.size() > 1) {
sorted.add(root.getLeft().getData());
}
return sorted;
}
// inserting a student to the heap
public void insert(Student stu) {
if (position == 1) { // first one is node
root = new Node<Student>(stu, null);
lastInserted = root;
} else {
// get parent of new position for node
Node<Student> parent = getParentNodeInsert(position);
Node<Student> newNode = new Node<Student>(stu, parent);
// set the node to correct child
if (parent.getLeft() == null) {
parent.setLeft(newNode);
} else {
parent.setRight(newNode);
}
lastInserted = newNode;
}
// heapify from that node up to root
heapify(lastInserted);
position++;
}
// swapping the data of two nodes
public void swapData(Node<Student> x, Node<Student> y) {
Student temp = x.getData();
x.setData(y.getData());
y.setData(temp);
}
// getting parent node of last inserted
public Node<Student> getParentNodeInsert(int position) {
Node<Student> cur = root; // start at top
ArrayList<String> path = getPath(position);
// loop through path to node
for (int i = path.size() - 1; i >= 0; i--) {
Node<Student> orig = cur; // for null pointers
// follow path
if (path.get(i).equals("Right")) {
cur = cur.getRight();
} else {
cur = cur.getLeft();
}
if (cur == null) {
return orig;
}
}
return cur;
}
// getting parent node of last inserted
public Node<Student> getParentNodeDelete(int position) {
Node<Student> cur = root; // start at top
ArrayList<String> path = getPath(position);
// loop through path to node
for (int i = path.size() - 1; i >= 0; i--) {
// follow path
if (path.get(i).equals("Right")) {
cur = cur.getRight();
} else {
cur = cur.getLeft();
}
}
return cur.getParent();
}
// getting the path to a particular node
public ArrayList<String> getPath(int position) {
ArrayList<String> path = new ArrayList<String>();
// calculating values to determine node's location
int level = (int) Math.floor(Math.log(position) / Math.log(2));
int maxLevel = (int) Math.pow(2, level);
int maxTotal = (int) (Math.pow(2, level + 1) - 1);
int spot = maxLevel - (maxTotal - position);
// traverse whole tree
while (level > 0) {
if (spot % 2 == 0) { // even is right child
path.add("Right");
} else { // odd is right child
path.add("Left");
}
// how far within the row the node is
double percentage = spot / (double) maxLevel;
maxLevel /= 2;
spot = (int) Math.ceil(percentage * maxLevel);
level--;
}
return path;
}
// deleting a student from a list
public static boolean deleteStudent(String name, ArrayList<Student> list) {
for (int i = 0; i < list.size(); i++) {
// if name is found then remove it
if (list.get(i).getName().equalsIgnoreCase(name)) {
list.remove(i);
return true;
}
}
return false;
}
}