137 lines
4.0 KiB
C++
137 lines
4.0 KiB
C++
|
// tll.cpp
|
||
|
|
||
|
#include "tll.h"
|
||
|
|
||
|
// data structures:
|
||
|
// node for a linked list
|
||
|
template <class Elem> class LLNode {
|
||
|
public:
|
||
|
Elem elem; // the element at this node
|
||
|
LLNode<Elem> *next; // pointer to the next node
|
||
|
};
|
||
|
//===========================================================================
|
||
|
template <class Elem> LinkedList<Elem>::LinkedList(void) {
|
||
|
root = NULL;
|
||
|
length = 0;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> LinkedList<Elem>::LinkedList(const LinkedList<Elem> &llist) {
|
||
|
root = NULL;
|
||
|
LLNode<Elem> *temp_ptr = llist.root;
|
||
|
while (temp_ptr) {
|
||
|
Insert(temp_ptr->elem);
|
||
|
temp_ptr = temp_ptr->next;
|
||
|
}
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> LinkedList<Elem> &LinkedList<Elem>::operator = (
|
||
|
const LinkedList<Elem> &llist) {
|
||
|
root = NULL;
|
||
|
LLNode<Elem> *temp_ptr = llist.root;
|
||
|
while (temp_ptr) {
|
||
|
Insert(temp_ptr->elem);
|
||
|
temp_ptr = temp_ptr->next;
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
//============================================================================
|
||
|
template <class Elem> LinkedList<Elem>::~LinkedList(void) {
|
||
|
if (root) {
|
||
|
LLNode<Elem> *temp_ptr = root->next, *next_temp_ptr;
|
||
|
delete root;
|
||
|
while (temp_ptr) {
|
||
|
next_temp_ptr = temp_ptr->next;
|
||
|
delete temp_ptr;
|
||
|
temp_ptr = next_temp_ptr;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
//============================================================================
|
||
|
template <class Elem> void LinkedList<Elem>::Clear(void) {
|
||
|
if (root) {
|
||
|
LLNode<Elem> *temp_ptr = root->next, *next_temp_ptr;
|
||
|
delete root;
|
||
|
while (temp_ptr) {
|
||
|
next_temp_ptr = temp_ptr->next;
|
||
|
delete temp_ptr;
|
||
|
temp_ptr = next_temp_ptr;
|
||
|
}
|
||
|
}
|
||
|
root = NULL;
|
||
|
length = 0;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> Elem *LinkedList<Elem>::Insert(const Elem &elem) {
|
||
|
if (!root) {
|
||
|
root = new LLNode<Elem>;
|
||
|
root->elem = elem;
|
||
|
root->next = NULL;
|
||
|
length++;
|
||
|
return &(root->elem);
|
||
|
} else {
|
||
|
if (!Search(elem)) { // only put in if it is not already in - this is ineff.
|
||
|
LLNode<Elem> temp_node;
|
||
|
temp_node.elem = root->elem;
|
||
|
temp_node.next = root->next;
|
||
|
root->elem = elem;
|
||
|
root->next = new LLNode<Elem>;
|
||
|
root->next->elem = temp_node.elem;
|
||
|
root->next->next = temp_node.next;
|
||
|
length++;
|
||
|
return &(root->elem);
|
||
|
} else { // put the elem back in the same place
|
||
|
root->elem = elem;
|
||
|
return &(root->elem);
|
||
|
}
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> Elem *LinkedList<Elem>::Search(const Elem &elem) {
|
||
|
LLNode<Elem> *curr_ptr = root;
|
||
|
while (curr_ptr) {
|
||
|
if (curr_ptr->elem == elem)
|
||
|
return &(curr_ptr->elem);
|
||
|
// this is very important, because they may not be completely the same,
|
||
|
// since the comparison could be done on a key only
|
||
|
else curr_ptr = curr_ptr->next;
|
||
|
}
|
||
|
return NULL;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> void LinkedList<Elem>::Write(ostream &s) {
|
||
|
LLNode<Elem> *curr_ptr = root;
|
||
|
while (curr_ptr) {
|
||
|
s<<(curr_ptr->elem)<<" ";
|
||
|
curr_ptr = curr_ptr->next;
|
||
|
}
|
||
|
}
|
||
|
//=============================================================================
|
||
|
template <class Elem> ostream &operator<<(ostream &s, LinkedList<Elem> &ll) {
|
||
|
ll.Write(s);
|
||
|
return s;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> int LinkedList<Elem>::DeleteNext(Elem &elem) {
|
||
|
if (!root) return 0;
|
||
|
elem = root->elem;
|
||
|
LLNode<Elem> *kill_ptr = root;
|
||
|
root = root->next;
|
||
|
delete kill_ptr;
|
||
|
length--;
|
||
|
return 1;
|
||
|
}
|
||
|
//===========================================================================
|
||
|
template <class Elem> int LinkedList<Elem>::GetNext(Elem &elem, int start) {
|
||
|
if (start) get_next_ptr = root;
|
||
|
if (get_next_ptr) {
|
||
|
elem = get_next_ptr->elem;
|
||
|
get_next_ptr = get_next_ptr->next;
|
||
|
return 1;
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|