Skip to content
Snippets Groups Projects
Commit c040a352 authored by ssridhr3's avatar ssridhr3
Browse files

added code file

parents
No related branches found
No related tags found
No related merge requests found
code.cpp 0 → 100755
nclude <iostream>
#include "list.h"
using namespace std;
/**
* @file list.cpp
* Doubly Linked List (MP 3).
*
* @author Chase Geigle
* @date (created) Fall 2011
* @date (modified) Spring 2012, Fall 2012
*
* @author Jack Toole
* @date (modified) Fall 2011
*/
/**
* Destroys the current List. This function should ensure that
* memory does not leak on destruction of a list.
*/
template <class T>
List<T>::~List()
{
/// @todo Graded in MP3.1
clear();
}
/**
* Destroys all dynamically allocated memory associated with the current
* List class.
*/
template <class T>
void List<T>::clear()
{
/// @todo Graded in MP3.1
ListNode * hnext;
while(head != NULL) {
hnext = head->next;
delete head;
head = hnext;
}
head = NULL;
tail = NULL;
}
/**
* Inserts a new node at the front of the List.
* This function **SHOULD** create a new ListNode.
*
* @param ndata The data to be inserted.
*/
template <class T>
void List<T>::insertFront(T const & ndata)
{
/// @todo Graded in MP3.1
ListNode * n = new ListNode(ndata);
length++;
if(head == NULL && tail == NULL) {
head = n;
tail = head;
}
else if(head != NULL) {
head -> prev = n;
n -> next = head;
head = n;
head -> prev = NULL;
head -> next = n->next;
}
}
/**
* Inserts a new node at the back of the List.
* This function **SHOULD** create a new ListNode.
*
* @param ndata The data to be inserted.
*/
template <class T>
void List<T>::insertBack( const T & ndata )
{
/// @todo Graded in MP3.1
ListNode * n = new ListNode(ndata);
length++;
if(head == NULL && tail == NULL) {
tail = n;
head = tail;
}
else if(tail != NULL) {
tail -> next = n;
n -> prev = tail;
n -> next = NULL;
tail = n;
}
}
/**
* Reverses the current List.
*/
template <class T>
void List<T>::reverse()
{
reverse(head, tail);
}
/**
* Helper function to reverse a sequence of linked memory inside a List,
* starting at startPoint and ending at endPoint. You are responsible for
* updating startPoint and endPoint to point to the new starting and ending
* points of the rearranged sequence of linked memory in question.
*
* @param startPoint A pointer reference to the first node in the sequence
* to be reversed.
* @param endPoint A pointer reference to the last node in the sequence to
* be reversed.
*/
template <class T>
void List<T>::reverse( ListNode * & startPoint, ListNode * & endPoint )
{
/// @todo Graded in MP3.1
ListNode * currentln = startPoint;
ListNode * sp = startPoint;
//ListNode * eln = endPoint;
ListNode * n = startPoint;
//cout <<" startPoint= " << startPoint << " ep= " << endPoint << " length= " << length << endl;
//cout <<" startPoint->next = " << startPoint->next << " ep->prev= " << endPoint->prev << endl;
if(empty()) {
startPoint = NULL;
endPoint = NULL;
}
else if(length == 1) {
startPoint = endPoint;
}
/*else if((startPoint != endPoint) && (length == 2)) {
startPoint = endPoint;
endPoint = currentln;
}*/
if(length >= 2) {
while(currentln != endPoint->next && currentln != NULL) {
/*if(startPoint->prev != NULL) {
ListNode * T = endPoint;
ListNode * sprev = startPoint->prev;
endPoint = endPoint->prev;
startPoint->prev = T;
sprev->next = T;
endPoint->next = NULL;
*///}
/*ListNode * epprev = endPoint->prev;
ListNode * currprev = currentln->prev;
if(startPoint->prev != NULL && endPoint->next != NULL) {
eln = eln->prev;
endPoint->next = endPoint->prev;
endPoint->prev->next = endPoint;
currentln->prev = endPoint;
currprev->next = endPoint;
endPoint = eln;
*///}
n = currentln->next;
currentln->next = currentln->prev;
currentln->prev = n; //n
if(currentln == endPoint) {
break;
}
currentln = n;
}
startPoint = endPoint;
endPoint = sp;
}
//cout <<" startPoint= " << startPoint << " ep= " << endPoint << " length= " << length << endl;
//cout <<" startPoint->next = " << startPoint->next << " ep->prev= " << endPoint->prev << endl;
}
/**
* Reverses blocks of size n in the current List. You should use your
* reverse( ListNode * &, ListNode * & ) helper function in this method!
*
* @param n The size of the blocks in the List to be reversed.
*/
template <class T>
void List<T>::reverseNth( int n )
{
ListNode * curr = head;
ListNode * nxt = head;
int i;
ListNode * nepPrevIter = NULL;
ListNode * nepPrevIterS = NULL;
if(n<length && curr != NULL) {
for(i = 1; i <= length && curr != NULL; i=i+n) {
nxt = curr;
for(int j = 1; (j < n && nxt != NULL) ; j++) {
if(nxt->next != NULL) {
nxt = nxt->next;
}
}
if(nepPrevIter != NULL) {
nepPrevIter->next = nxt;
}
if(nxt == curr) {
break;
}
nepPrevIterS = nepPrevIter;
nepPrevIter = curr;
ListNode * nxtNextSaved = nxt->next;
reverse(curr,nxt);
if(nxt == head) {
head = curr;
}
if(curr == tail) {
nxt->next = NULL;
tail = nxt;
}
curr->prev = nepPrevIterS;
curr = nxtNextSaved;
}
}
else if(n>=length) {
reverse(head,tail);
}
/// @todo Graded in MP3.1
}
/**
* Modifies the List using the waterfall algorithm.
* Every other node (starting from the second one) is removed from the
* List, but appended at the back, becoming the new tail. This continues
* until the next thing to be removed is either the tail (**not necessarily
* the original tail!**) or NULL. You may **NOT** allocate new ListNodes.
* Note that since the tail should be continuously updated, some nodes will
* be moved more than once.
*/
template <class T>
void List<T>::waterfall()
{
/// @todo Graded in MP3.1
ListNode * curr = head;
ListNode * tnxt = curr;
ListNode * nxttwo = curr;
ListNode * t = tail;
int x = 0;
for(int i = 1; i <= length-1; i++) {
if(length == 1) {
break;
}
if((curr != NULL && curr->next != NULL && curr->next->next != NULL) || length == 3 || (curr == t && t->next != NULL)) {
ListNode * nxt = curr->next;
nxttwo = curr->next;
tnxt = curr->next->next;
curr->next = curr->next->next;
tnxt->prev = curr;
tail->next = nxt;
nxt->prev = tail;
nxt->next = NULL;
tail = nxt;
curr = tnxt;
}
//else {curr = nxttwo;}
if(length == 3) {
break;
}
}
}
/**
* Splits the given list into two parts by dividing it at the splitPoint.
*
* @param splitPoint Point at which the list should be split into two.
* @return The second list created from the split.
*/
template <class T>
List<T> List<T>::split(int splitPoint)
{
if (splitPoint > length)
return List<T>();
if (splitPoint < 0)
splitPoint = 0;
ListNode * secondHead = split(head, splitPoint);
int oldLength = length;
if (secondHead == head)
{
// current list is going to be empty
head = NULL;
tail = NULL;
length = 0;
}
else
{
// set up current list
tail = head;
while (tail->next != NULL)
tail = tail->next;
length = splitPoint;
}
// set up the returned list
List<T> ret;
ret.head = secondHead;
ret.tail = secondHead;
if (ret.tail != NULL)
{
while (ret.tail->next != NULL)
ret.tail = ret.tail->next;
}
ret.length = oldLength - splitPoint;
return ret;
}
/**
* Helper function to split a sequence of linked memory at the node
* splitPoint steps **after** start. In other words, it should disconnect
* the sequence of linked memory after the given number of nodes, and
* return a pointer to the starting node of the new sequence of linked
* memory.
*
* This function **SHOULD NOT** create **ANY** new List objects!
*
* @param start The node to start from.
* @param splitPoint The number of steps to walk before splitting.
* @return The starting node of the sequence that was split off.
*/
template <class T>
typename List<T>::ListNode * List<T>::split(ListNode * start, int splitPoint)
{
/// @todo Graded in MP3.2
if(splitPoint > this->length || splitPoint < 0 || start == NULL) {
return NULL;
}
ListNode * curr = start;
for(int i = 0; i < splitPoint && curr != NULL; i++) {
curr = curr->next;
}
ListNode * curr2 = curr->prev;
curr->prev = NULL;
curr2->next = NULL;
return curr;
}
/**
* Merges the given sorted list into the current sorted list.
*
* @param otherList List to be merged into the current list.
*/
template <class T>
void List<T>::mergeWith(List<T> & otherList)
{
// set up the current list
head = merge(head, otherList.head);
tail = head;
// make sure there is a node in the new list
if(tail != NULL)
{
while (tail->next != NULL)
tail = tail->next;
}
length = length + otherList.length;
// empty out the parameter list
otherList.head = NULL;
otherList.tail = NULL;
otherList.length = 0;
}
/**
* Helper function to merge two **sorted** and **independent** sequences of
* linked memory. The result should be a single sequence that is itself
* sorted.
*
* This function **SHOULD NOT** create **ANY** new List objects.
*
* @param first The starting node of the first sequence.
* @param second The starting node of the second sequence.
* @return The starting node of the resulting, sorted sequence.
*/
template <class T>
typename List<T>::ListNode * List<T>::merge(ListNode * first, ListNode * second)
{
/// @todo Graded in MP3.2
ListNode * temp = first;
ListNode * temp2 = second;
ListNode * nxt = NULL;
ListNode * nxt2 = NULL;
ListNode * prev = NULL;
ListNode * prev2 = NULL;
while(temp != NULL && temp2 != NULL) {
if(temp->data < temp2->data) {
if(temp->next != NULL && temp2->data < temp->next->data) {
nxt = temp->next;
nxt2 = temp2->next;
temp->next->prev = temp2;
temp->next = temp2;
temp2->prev = temp;
temp2->next = nxt;
temp = temp2;
temp2 = nxt2;
}
else {
if(temp->next == NULL) {
temp->next = temp2;
temp2->prev = temp;
temp = NULL;
}
else {temp = temp->next;}
}
}
else {
if(temp2->next != NULL && temp->data < temp2->next->data) {
nxt2 = temp2->next;
prev2 = temp->prev;
if(temp->prev != NULL) {
temp->prev->next = temp2;
}
temp2->next = temp;
temp2->prev = prev2;
temp->prev = temp2;
temp2 = nxt2;
if(temp->next == NULL) {
temp->next = nxt2 ;
nxt2->prev = temp ;
temp = NULL ;
} else {temp = temp->next;}
}
else {
nxt2 = temp2->next;
prev2 = temp->prev;
if(temp->prev != NULL) {
temp->prev->next = temp2;
}
temp2->next = temp;
temp2->prev = prev2;
temp->prev = temp2;
temp2 = nxt2;
}
}
}
if(first->data < second->data) {return first;}
else {return second;}
}
/**
* Sorts the current list by applying the Mergesort algorithm.
*/
template <class T>
void List<T>::sort()
{
if (empty())
return;
head = mergesort(head, length);
tail = head;
while (tail->next != NULL)
tail = tail->next;
}
/**
* Sorts a chain of linked memory given a start node and a size.
* This is the recursive helper for the Mergesort algorithm (i.e., this is
* the divide-and-conquer step).
*
* @param start Starting point of the chain.
* @param chainLength Size of the chain to be sorted.
* @return A pointer to the beginning of the now sorted chain.
*/
template <class T>
typename List<T>::ListNode * List<T>::mergesort(ListNode * start, int chainLength)
{
/// @todo Graded in MP3.2
if(chainLength == 1) {
return start;
}
if(start == NULL) {
return NULL;
}
int ns = (int)(chainLength/2);
int ns2 = (int)(chainLength-ns);
ListNode * curr = split(start,ns);//split current list into 2 parts
start = mergesort(start,ns);//sort first half
curr = mergesort(curr,ns2);//sort second half
start = merge(start,curr);//merge them together
return start;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment