I'm trying to code a binary tree search/insert/print(BFS) functions.
It compiles fine, but I keep getting segment faults when I try to insert new nodes. Consequently, I could not test the print function neither. Any suggestions, lads?
I did code the functions in a separate Binarytree.cpp file, by the way.
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
#include <vector>
using namespace std;
typedef struct Node{
int key;
struct Node* leftNode;
struct Node* rightNode;
//C++에서는 struct의 constructor 가능
Node(int _key){key = _key;};
} Node;
class BinaryTree
{
private:
static Node* rootNode;
public:
static Node* search(int searchkey){
Node* curNode = rootNode;
while (curNode){
if (searchkey == curNode->key){
break;
} else if (searchkey < curNode->key){
curNode = curNode->leftNode;
} else {
curNode = curNode->rightNode;
}
}
return curNode;
}
static bool insert(int insertkey){
Node* curNode = search(insertkey);
if (insertkey == search(insertkey)->key){
cout << "Key already exits" << endl;
return false;
}
if (!rootNode){
rootNode = new Node(insertkey);
return true;
} else {
Node* newNode = new Node(insertkey);
newNode = search(insertkey);
return true;
}
}
static void print(){
//Node* rootNode = getRoot();
vector<Node*> v;
if (rootNode == NULL){
cout << "Binary tree is empty." << endl;
return;
} else {
v.push_back(rootNode);
cout << rootNode->key << endl;
}
while (!v.empty()){
Node* temp = v.front();
v.erase(v.begin());
if (temp->leftNode){
v.push_back(temp->leftNode);
cout << temp->leftNode->key << endl;
}
if (temp->rightNode){
v.push_back(temp->rightNode);
cout << temp->rightNode->key << endl;
}
}
}
};
Node* BinaryTree::rootNode = NULL;
#endif
Here in insert:
Node* curNode = search(insertkey);
When you call insert the first time, curNode will be NULL. In the following condition:
if (insertkey == search(insertkey)->key){
cout << "Key already exits" << endl;
return false;
}
you are trying to deference a NULL pointer by doing search(insertkey)->key. This causes the seg fault.
Here is the output from backtrace in gdb on my machine:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004009a3 in BinaryTree::insert (insertkey=1) at binarytree.h:38
38 if (insertkey == search(insertkey)->key){
(gdb) backtrace
#0 0x00000000004009a3 in BinaryTree::insert (insertkey=1) at binarytree.h:38
A quick way you can fix this is check if the return from search is NULL first, then move on to other cases.
Related
I am trying to create a binary tree using C++ classes and pointers. The tree is being initialized properly. However, when I add nodes to the tree, instead of adding them to the left or right sub-tree, the root node gets overwritten. I tried printing the inorder value to check if the nodes are added correctly or not, but that also prints nothing.
Here is the code for the same.
#include <iostream>
#include <conio.h>
#include <stdlib.h>
#include <cstdio>
using namespace std;
class Node{
private:
Node *left;
Node *right;
public:
int number;
Node(int number){
this->number = number;
this->left = NULL;
this->right = NULL;
}
void set_left_node(Node *node){
this->left = node;
}
void set_right_node(Node *node){
this->right = node;
}
Node* read_left_node(){
return this->left;
}
Node* read_right_node(){
return this->right;
}
};
class Binary_Tree{
public:
Node *root;
Binary_Tree(){
this->root = NULL;
}
Node* read_root(){
return this->root;
}
Node* insert_node(Node *root, Node node){
if(!root){
root = &node;
cout << "Inserted " << node.number << " " << root << endl;
return root;
}
else{
cout << "Root and node values " << root->number << " " << node.number << endl;
if(root->number < node.number){
root->set_right_node(insert_node(root->read_right_node(), node));
}
else{
root->set_left_node(insert_node(root->read_left_node(), node));
}
}
return root;
}
void inorder(Node *root){
if (root != NULL){
inorder(root->read_left_node());
cout<<root->number<<" ";
inorder(root->read_right_node());
}
}
};
int main(){
Binary_Tree bt = Binary_Tree();
bt.root = bt.insert_node(bt.root, Node(34));
bt.root = bt.insert_node(bt.root, Node(17));
bt.root = bt.insert_node(bt.root, Node(56));
cout << "Inorder" << endl;
bt.inorder(bt.root);
return 0;
}
Output:
I am new to programming in C++ but I am trying to create a Binary Search Tree.
The program seems to compile fine but it gives me this error:
Unhandled exception at 0x009229B7 in Lab001_CS3.exe: 0xC00000FD: Stack
overflow (parameters: 0x00000001, 0x00AD2FBC).
when I try to run it. The error occurs on this line of code:
void insert(int value) {
...
}
I am not sure what I am doing wrong, and I have never gotten this error before.
Here is the code:
#include <iostream>
using namespace std;
//create a node struct
struct node {
//member variables
int key;
node* left;
node* right;
//default constructor
node() {
key = 0;
left = NULL;
right = NULL;
cout << "a new node is created" << endl;
}
//constructor so can create a node in one line
node(int k) {
key = k;
left = NULL;
right = NULL;
cout << "a new node is created" << endl;
}
};
class Tree {
public:
//root node
node root;
//default constructor
Tree() {
root.key = 0;
root.left = NULL;
root.right = NULL;
}
//constructor to create the root node
Tree(int data) {
//set the data to the key
//set the right and left pointers to null
root.key = data;
root.left = NULL;
root.right = NULL;
}
//print the root node
void printRootNode() {
cout << "Root Node - Key: " << root.key << endl;
}
//insert functions
void insert(int value) {
/* If the newNode's key is less than the root key, traverse left
*/
if (value < root.key) {
/* if the left node is NULL */
if (root.left == NULL) {
root.left = new node(value);
cout << "assigned left" << endl;
}
else {
/* if the left node is important */
insert(value);
cout << "recurse" << endl;
}
}
if (value > root.key) {
/* if the right node is NULL */
if (root.right == NULL) {
root.right = new node(value);
cout << "assigned right" << endl;
}
else {
/* if the right node is important */
insert(value);
cout << "recurse" << endl;
}
}
}
};
//print inorder
void inorder(node* rt) {
//base
if (rt == NULL) {
return;
}
inorder(rt->left);
cout << " " << rt->key << endl;
inorder(rt->right);
}
int main() {
//create a tree for a root node
Tree t(16);
t.printRootNode();
//create newNode
node n1(20);
node n2(31);
//insert the new nodes
t.insert(20);
t.insert(31);
//keep the window from closing
system("pause");
}
Thank you for any help.
In your insert()
if (value < root.key) {
/* if the left node is NULL */
if (root.left == NULL) {
root.left = new node(value);
cout << "assigned left" << endl;
}
else {
/* if the left node is important */
insert(value);
cout << "recurse" << endl;
}
}
let's take this go left snippet as example, if root.left != NULL the code will enter else block and recursively call insert(value) forever, which cause stack overflow, the correct operation is make current node move to root.left, and then call insert(value) recursively.
also you don't need node class at all, tree class can do all the things.
again, here is not a good place for help you debug, you need to learn how to do this yourself :-).
I am trying to create a binary tree that when you try to add a new node to that, it adds the node to first position that is nullptr.
actually making a complete binary tree.
Look at the code below:
#include <iostream>
#include <queue>
using namespace std;
class node{
private:
char data;
node* right;
node* left;
public:
node(char n){
data = n;
left = nullptr;
right = nullptr;
}
char getdata(){
return data;
}
friend class binTree;
};
class binTree{
private:
node *root;
public:
binTree(){
root = nullptr;
}
binTree(node *root){
this->root = root;
}
node* getRoot(){
return this->root;
}
void addNode(char data){
cout << "adding " << data << endl;
if(root == nullptr) {
root = new node(data);
return;
}
queue<node*> Q;
Q.push(root);
node* toadd;
while(true) {
node* toadd = Q.front();
Q.pop();
Q.push(toadd->left);
Q.push(toadd->right);
if(toadd->left == nullptr) break;
if(toadd->right == nullptr) break;
}
if((toadd->left) == nullptr)
{
cout << "add data to the left of " << toadd -> data << endl;
toadd->left = new node(data);
} else if((toadd -> right) == nullptr){
cout << "add data to the right of " << toadd -> data << endl;
toadd->right = new node(data);
} else {
cout << "toadd left and right are not nullptr" << endl;
}
}
};
int main()
{
binTree bin;
string s = "abcdefg";
cout << s << endl << endl;
for(int i = 0; i < s.size(); i++)
{
bin.addNode(s[i]);
}
}
when I run this code the output is:
abcdefg
adding a
adding b
toadd left and right are not nullptr
adding c
toadd left and right are not nullptr
adding d
toadd left and right are not nullptr
adding e
toadd left and right are not nullptr
adding f
toadd left and right are not nullptr
adding g
toadd left and right are not nullptr
the strange part is when printing "toadd left and right are not nullptr"
because there is a while(true) and the only exit conditions are:
if(toadd->left == nullptr) break;
if(toadd->right == nullptr) break;
so one of these conditions were true that we could break the loop;
so we should enter one of if or else if part of the following code (after the while) but surprisingly we enter the else part and end of printing "toadd left and right are not nullptr".
can anyone explain this behavior?
You've defined toadd twice, once before the loop and once inside. Easy mistake to make.
I'm writing a program for a homework assignment that creates and manipulates a linked list. I am encountering an "EXC_BAD_ACCESS" error with the Node::SetData function in Node.cpp, as well as with a line in List::Add_End in List.cpp (specifically "current->SetData(data);") and a line in main.cpp for some reason (specifically "// Add_End nodes to the list"). I assume that once the Node::SetData error is fixed, these other errors will resolve themselves.
After searching through Stack Overflow and Google, I cannot determine why this error is occurring. I thought this question (New to C++, "EXC_BAD_ACCESS" error I don't understand) would help, but I'm still having issues.
What coding error(s) have I made?
main.cpp
#include <iostream>
#include <cstddef>
using namespace std;
#include "List.h"
int main()
{
// New list
List list;
Node *answer;
// Add_End nodes to the list
list.Add_End(111);
list.Print();
list.Add_End(222);
list.Print();
list.Add_End(333);
list.Print();
list.Add_End(444);
list.Print();
list.Add_End(555);
list.Print();
// Delete nodes from the list
list.Delete(444);
list.Print();
list.Delete(333);
list.Print();
list.Delete(222);
list.Print();
list.Delete(555);
list.Print();
list.Delete(111);
list.Print();
cout << "Testing Add_Front: and others" << endl;
list.Add_Front(888);
list.Print();
list.Add_Front(999);
list.Print();
list.Add_Front(49);
list.Print();
cout << "Checking find function" << endl;
answer = list.Find(888);
cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
cout << "Checking find function" << endl;
answer = list.Find(999);
cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
cout << "Checking find function" << endl;
answer = list.Find(49);
cout << "Value for node returned by find function call with 888 is " << answer->Data() << "." << endl;
cout << "Call find function with value not in list." << endl;
answer = list.Find(7);
if (answer == NULL)
{
cout << "returned null pointer since 7 not found" << endl;
}
else
{
cout << "in else of answer == NULL where Value for node returned by find function call with 7 is " << answer->Data() << "." << endl;
}
cout << "testing delete_front: " << endl;
list.Delete_Front();
list.Print();
cout << "testing delete_end: " << endl;
list.Delete_End();
list.Print();
return 0;
}
List.h
#ifndef LIST_H
#define LIST_H
#include <cstddef>
#include "Node.h"
class List
{
private:
Node* head;
public:
List();
void Add_End(int data);
void Delete(int data);
void Delete_Front();
void Add_Front(int data);
void Delete_End();
Node* Find(int data);
void Print();
};
#endif
List.cpp
#include <iostream>
#include <cstddef>
using namespace std;
#include "List.h"
List::List()
{
head = NULL;
return;
}
void List::Add_End(int data)
{
Node* current;
Node* newEnd = new Node();
for (current = head; current != NULL; current = current->Next())
{}
current->SetData(data);
current->SetNext(newEnd);
newEnd->SetData(NULL);
newEnd->SetNext(NULL);
return;
}
void List::Delete(int data) {
/*
FILL IN CODE (will do later)
*/
return;
}
void List::Delete_Front()
{
/*
FILL IN CODE (will do later)
*/
return;
}
void List::Add_Front(int data)
{
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(head);
head = newNode;
return;
}
void List::Delete_End()
{
if (head == NULL)
{
cout << "List has no member so cannot delete end" << endl;
return;
}
// check if one in length
if (head->Next() == NULL)
{
head = NULL;
return;
}
// 2 or greater in length
Node* current;
Node* prev;
prev = head;
for (current = head->Next(); current->Next() != NULL; current = current->Next())
{
prev = current;
}
prev->SetNext(NULL);
return;
}
Node* List::Find(int data)
{
Node* current;
for (current = head; current != NULL && current->Data() != data; current = current->Next())
{}
if(current == NULL)
{
cout << "Did not find " << data << "." << endl;
return NULL;
}
else // found
{
cout << "Found " << data << "." << endl;
return current;
}
}
void List::Print()
{
Node* current;
for (current = head; current != NULL; current = current->Next())
{
cout << current->Data() << " ";
}
cout << endl;
return;
}
Node.h
#ifndef NODE_H
#define NODE_H
class Node
{
private:
int data;
Node* next;
public:
Node();
void SetData(int aData);
void SetNext(Node* aNext);
int Data();
Node* Next();
};
#endif
Node.cpp
#include <cstddef>
#include "Node.h"
Node::Node()
{
this->SetData(NULL);
this->SetNext(NULL);
return;
}
void Node::SetData(int aData)
{
this->data = aData;
return;
}
void Node::SetNext(Node* aNext)
{
this->next = aNext;
return;
}
int Node::Data()
{
return data;
}
Node* Node::Next()
{
return next;
}
While calling current->SetData for the first time (see below) current is NULL and so you get page fault when accessing it (page fault is the error modern OSes give you if you try to access unallocated memory. Under wndows the term usually is Access violation.)
void List::Add_End(int data)
{
Node* current;
Node* newEnd = new Node();
for (current = head; current != NULL; current = current->Next())
{}
current->SetData(data);
current->SetNext(newEnd);
newEnd->SetData(NULL);
newEnd->SetNext(NULL);
return;
}
I managed to correct the code, so I'll explain what I did in case someone else encounters the same problem.
ALTERATION: Before I explain the fix, let me explain a change I made. The last node of the linked list can hold a data value itself, not just NULL (i.e., the last node's data does not need to be NULL, but its next should be NULL), so I thought this would be better. The code reflects this in every location where it matters, such as the List::Add_End(int data) function.
THE FIX: I modified the List constructor to create a head node for the list. So, the linked list will always have at least one node, even if the list is empty. I will explain how the program discerns between empty and nonempty lists later.
Here is the original constructor:
List::List()
{
head = NULL;
return;
}
Here is the new constructor:
List::List()
{
Node* headNode = new Node();
head = headNode;
return;
}
Why make this modification? As far as I can tell, I encountered the EXC_BAD_ACCESS error because the List::Add_End(int data) function tried to manipulate the linked list's head as if it were a node object, when actually it was not. (I believe this is what marom meant in his answer to this question.) This is why I altered the coding such that the list always contains a head node, even when the list is empty.
Discerning between empty and nonempty lists. I altered the Node constructor to set data to the integer -1122334455, instead of NULL like I originally did. So, if the list is empty, then head->Data() (i.e., the head node's data) is -112233455 and head->Next() (i.e., the head node's next) is NULL. The downside to this approach is that it's impossible to have a one-item list containing the integer -1122334455, but I figure this number is likely to be unneeded. As long as the list has at least two items, head->Data() can be -1122334455.
NEW CODE: The rest of the code reflects these modifications. Since I only made significant changes to List.cpp and Node.cpp, I have reproduced only them below. The other three program files are essentially unchanged. FYI, there are many redundant return's and this's that I didn't bother to delete.
List.cpp
#include <iostream>
#include <cstddef>
using namespace std;
#include "List.h"
// -1122334455 is an arbitrary integer that is likely to never be needed by the user
List::List()
{
Node* headNode = new Node();
head = headNode;
return;
}
Node* List::Add_End(int data)
{
// if list is empty (i.e., list has only head node with data == -1122334455 & next == NULL)
if (head->Data() == -1122334455 && head->Next() == NULL)
{
head->SetData(data);
return head;
}
// if list is nonempty
else
{
Node* current;
Node* newEnd = new Node();
for (current = head; current->Next() != NULL; current = current->Next())
{}
current->SetNext(newEnd);
newEnd->SetData(data);
newEnd->SetNext(NULL);
return newEnd;
}
}
void List::Delete(int data)
{
Node* prev;
Node* current;
// if list is empty
if (head->Data() == -1122334455 && head->Next() == NULL)
{
cout << "Cannot delete this datum because list is empty." << endl;
return;
}
// if list contains 1 element
if (head->Data() == data && head->Next() == NULL)
{
head->SetData(-1122334455);
return;
}
else if (head->Data() != data && head->Next() == NULL)
{
cout << "Datum not found in list." << endl;
return;
}
// if list contains 2 or more elements
prev = head;
for (current = head->Next(); current->Data() != data && current->Next() != NULL; current = current->Next())
{
prev = prev->Next();
}
if (current->Data() == data && current->Next() != NULL)
{
prev->SetNext(current->Next());
delete current;
return;
}
else if (current->Data() == data && current->Next() == NULL)
{
prev->SetNext(NULL);
delete current;
return;
}
else
{
cout << "Datum not found in list." << endl;
return;
}
}
void List::Delete_Front()
{
Node* origHead = head;
Node* newHead = head->Next();
head = newHead;
delete origHead;
return;
}
void List::Add_Front(int data)
{
// if list is empty
if (head->Data() == -1122334455 && head->Next() == NULL)
{
head->SetData(data);
return;
}
// if list is nonempty
Node* newNode = new Node();
newNode->SetData(data);
newNode->SetNext(head);
head = newNode;
return;
}
void List::Delete_End()
{
if (head->Data() == -1122334455 && head->Next() == NULL)
{
cout << "List has no member so cannot delete end" << endl;
return;
}
// check if one in length
else if (head->Data() != -1122334455 && head->Next() == NULL)
{
head->SetData(-1122334455);
return;
}
// 2 or greater in length
else
{
Node* current;
Node* prev;
prev = head;
for (current = head->Next(); current->Next() != NULL; current = current->Next())
{
prev = current;
}
prev->SetNext(NULL);
return;
}
}
Node* List::Find(int data)
{
Node* current;
for (current = head; current != NULL && current->Data() != data; current = current->Next())
{}
if (current == NULL)
{
cout << "Did not find " << data << "." << endl;
return NULL;
}
else // found
{
cout << "Found " << data << "." << endl;
return current;
}
}
void List::Print()
{
if (head->Data() == -1122334455 && head->Next() == NULL)
{
cout << "List is empty." << endl;
return;
}
Node* current;
for (current = head; current != NULL; current = current->Next())
{
cout << current->Data() << " ";
}
cout << endl;
return;
}
Node.cpp
#include <cstddef>
#include "Node.h"
Node::Node()
{
// -1122334455 is an arbitrary integer that is likely to never be needed by the user
this->SetData(-1122334455);
this->SetNext(NULL);
return;
}
void Node::SetData(int aData)
{
this->data = aData;
return;
}
void Node::SetNext(Node* aNext)
{
this->next = aNext;
return;
}
int Node::Data()
{
return this->data;
}
Node* Node::Next()
{
return this->next;
}
I keep getting a Segmentation fault (core dumped) error every time I try to run my code with g++ on Linux. It compiles fine, but then that happens ... All the functions (remove, add and print) seem to have the same problem, I can't seem to figure out what's wrong... Please heeeelppp.
#include <iostream>
#include <string>
using namespace std;
//Create a node struct
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
//set to NULL
Queue::Queue() {
head = tail = NULL;
size = 0;
}
//destructor
//call remove until empty
Queue::~Queue() {
while (!isEmpty())
remove();
}
//adds a node with the given data at the back of the queue
void Queue::add(int d) {
Node *temp = new Node();
temp->data = d;
temp->next = NULL;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
//removes the node at the head of the queue and returns its data
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *temp = new Node;
temp = head;
int value = head->data;
//moves pointer to next node
head = head->next;
cout << "Removed: " << head->data << endl;
size--;
delete temp;
return value;
}
}
//determines if the queue is empty
bool Queue::isEmpty() {
return (size == 0);
}
//prints the contents of the queue from front to back, or front
//to back, depending on the value of the parameter
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p = new Node;
if (o == true) {
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
p = head;
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
p = tail;
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(8);
return 0;
}
EDIT: I've made some changes to the code... But I'm still getting the same error. I assume I'm not updating the head and the tail and/or the next and prev nodes correctly... I don't know why it's wrong or what I'm missing, though.
#include <iostream>
#include <string>
using namespace std;
struct Node {
int data;
Node *next;
Node *prev;
};
class Queue {
private:
Node *head;
Node *tail;
int size;
public:
Queue();
~Queue();
void add(int d);
int remove();
bool isEmpty();
void printQueue(bool o);
};
Queue::Queue() {
head = tail = NULL;
size = 0;
}
Queue::~Queue() {
while (!isEmpty())
remove();
}
void Queue::add(int d) {
Node *temp = new Node;
temp->data = d;
temp->next = NULL;
temp->prev = tail;
if (isEmpty()) {
//add to head
head = temp;
} else {
//append
tail->next = temp;
tail = temp;
cout << "Added: " << tail->data << endl;
}
size++;
}
int Queue::remove() {
if (isEmpty()) {
cout << "The queue is empty." << endl;
return 0;
} else {
Node *temp = head;
int value = head->data;
cout << "Removed: " << head->data << endl;
//moves pointer to next node
head = head->next;
head->prev = NULL;
size--;
delete temp;
return value;
}
}
bool Queue::isEmpty() {
return (size == 0);
}
void Queue::printQueue(bool o) {
if (isEmpty()) {
cout << "The queue is empty." << endl;
} else {
Node *p;
if (o == true) {
p = head;
cout << "Printing in front to back:" << endl;
//print front to back
while(p != NULL) {
cout << p->data << " ";
p = p->next;
}
} else if (o == false) {
p = tail;
cout << "Printing in back to front:" << endl;
//print back to front
while (p != NULL) {
cout << p->data << " ";
p = p->prev;
}
}
}
}
int main() {
Queue q;
q.add(9);
q.add(10);
q.add(11);
q.add(12);
q.add(13);
q.add(14);
q.add(15);
q.add(16);
q.remove();
q.remove();
q.printQueue(true);
q.printQueue(false);
return 0;
}
Lots of problems:
You have a double-linked Node but never update its prev member in the add/remove methods.
You are keeping track of both the Queue head/tail but don't properly update them when you add/remove nodes.
Both your forward and reverse loops in printQueue() are wrong and result in an infinite loop for any queue with 2 or more elements. Queue output should be just something like:
Node *p = head;
while (p != NULL)
{
cout << p->data << " ";
p = p->next;
}
Possible null pointer deference in remove() at cout << "Removed: " << head->data << endl; since you've already moved the head pointer by this time. Move the head after the cout.
Memory leak in Queue::remove() at Node *temp = new Node;. Just do Node* temp = head;.
Memory leak in Queue::printQueue() at Node *p = new Node;. You don't need to allocate a node here.
No return value in remove() for an empty queue.
Edit
Don't forget to initialize the tail when adding a node to an empty list:
if (isEmpty()) {
head = temp;
tail = temp;
}
To remove a node from the head of a non-empty list it should be something like:
Node *temp = head;
head = head->next;
if (head) head->prev = NULL;
size--;
delete temp;
if (isEmpty()) tail = NULL;