0% found this document useful (0 votes)
115 views

Lab 2: Doubly LL + Stack + Queue + Sorting

The document describes an exercise to implement a queue data structure using a doubly linked list. It provides code for a Queue and DLinkedList class and asks the student to implement the Queue methods by using the existing DLinkedList methods. These include push(), pop(), top(), empty(), size(), and clear(). It also provides examples of expected test cases and results.

Uploaded by

Cao Minh Quang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
115 views

Lab 2: Doubly LL + Stack + Queue + Sorting

The document describes an exercise to implement a queue data structure using a doubly linked list. It provides code for a Queue and DLinkedList class and asks the student to implement the Queue methods by using the existing DLinkedList methods. These include push(), pop(), top(), empty(), size(), and clear(). It also provides examples of expected test cases and results.

Uploaded by

Cao Minh Quang
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

LAB 2: DOUBLY LL + STACK + QUEUE + SORTING

EX3:
Implement all methods in class Queue with template type T. The description of each method is
written as comment in frame code.

#ifndef QUEUE_H
#define QUEUE_H
#include "DLinkedList.h"
template<class T>
class Queue {
protected:
DLinkedList<T> list;
public:
Queue() {}
void push(T item) ;
T pop() ;
T top() ;
bool empty() ;
int size() ;
void clear() ;
};

#endif /* QUEUE_H */

You can use all methods in class DLinkedList without implementing them again. The description of
class DLinkedList is written as comment in frame code.
template <class T>
class DLinkedList
{
public:
class Node; //forward declaration
protected:
Node* head;
Node* tail;
int count;
public:
DLinkedList() ;
~DLinkedList();
void add(const T& e);
void add(int index, const T& e);
T removeAt(int index);
bool removeItem(const T& removeItem);
bool empty();
int size();
void clear();
T get(int index);
void set(int index, const T& e);
int indexOf(const T& item);
bool contains(const T& item);
};

void push(T item) {


// TODO: Push new element into the end of the queue
this->list.add(item);
}
T pop() {
// TODO: Remove an element in the head of the queue
return this->list.removeAt(0);
}
T top() {
// TODO: Get value of the element in the head of the queue
return this->list.get(0);
}
bool empty() {
// TODO: Determine if the queue is empty
return this->list.empty();
}
int size() {
// TODO: Get the size of the queue
return this->list.size();
}
void clear() {
// TODO: Clear all elements of the queue
this->list.clear();
}

EX5:
You are keeping score for a basketball game with some new rules. The game consists of several
rounds, where the scores of past rounds may affect future rounds' scores.

At the beginning of the game, you start with an empty record. You are given a list of strings ops,
where ops[i] is the operation you must apply to the record, with the following rules:

• A non-negative integer x (from 0 to 9) - record a new score of x


• '+' - Record a new score that is the sum of the previous two scores. It is guaranteed there will
always be two previous scores.
• 'D' - Record a new score that is double the previous score. It is guaranteed there will always
be a previous score.
• 'C' - Invalidate the previous score, removing it from the record. It is guaranteed there will
always be a previous score.

Finally, return the sum of all scores in the record.


For example:
ops = "52CD+"

• '5' - add to the record. Record now is [5]


• '2' - add to the record. Record now is [5,2]
• 'C' - invalid the previous score (2). Record now is [5]
• 'D' - Record new score that is double of previous score (5*2). Record now is [5,10]
• '+' - Record a new score that is the sum of the previous two scores. Record now is [5,10,15]

Return the sum: 5+10+15 = 30

For example:

Test Result

cout << baseballScore("52CD+"); 30

cout << baseballScore("524CD9++"); 55

template <class T>

class _Stack{

public:

class Node;

private:

Node* head; //Head is top of the stack

Node* tail; //Tail is the bottom of the stack

int count = 0;

public:

void push(const T &c);

int pop();

T top();

bool isEmpty();

int size();

T prevHead(){//Return data in the previous node of the head

Node* ptr = this->head->next;

T dataOut = ptr->data;

return dataOut;

public:
class Node{

private:

T data;

Node* next;

friend class _Stack<T>;

public:

Node() {

next = 0;

Node(Node* next) {

this->next = next;

Node(T data, Node* next) {

this->data = data;

this->next = next;

};

};

template <class T>

void _Stack<T>::push(const T &c){

Node* pNew = new Node(c,nullptr);

if (this->count == 0)

this->tail = pNew;

else

pNew->next = this->head;

this->head = pNew;

this->count++;

template <class T>


int _Stack<T>::pop(){

Node* dltPtr = this->head;

if (this->count == 0) return 0;

if (this->count == 1){

this->head = nullptr;

this->tail = nullptr;

this->head = dltPtr->next;

delete dltPtr;

this->count--;

return 1;

template <class T>

T _Stack<T>::top(){

if (this->count == 0) return 0;

T dataOut = this->head->data;

return dataOut;

template <class T>

bool _Stack<T>::isEmpty(){

if (this->count == 0) return true;

else return false;

template <class T>

int _Stack<T>::size(){

return this->count;

int baseballScore(string ops){

/*TODO*/

_Stack<int> record;
for (size_t i=0; i<ops.length(); i++){

if (ops[i] > '0' && ops[i] <= '9'){

int value = int(ops[i] - '0');

record.push(value);

if (ops[i] == 'C')

record.pop();

if (ops[i] == 'D'){

int value = (record.top())*2;

record.push(value);

if (ops[i] == '+'){

int value = record.prevHead() + record.top();

record.push(value);

int sum = 0;

while (record.size() != 0){

sum += record.top();

record.pop();

return sum;

Test Expected Got

cout << baseballScore("5C4C2C11+D3"); 11 11


EX6:
Implement all methods in class Stack with template type T. The description of each method is
written as comment in frame code.

#ifndef STACK_H

#define STACK_H
#include "DLinkedList.h"
template<class T>
class Stack {
protected:
DLinkedList<T> list;
public:
Stack() {}
void push(T item) ;
T pop() ;
T top() ;
bool empty() ;
int size() ;
void clear() ;
};

#endif

You can use all methods in class DLinkedList without implementing them again. The description of
class DLinkedList is written as comment in frame code.

template <class T>


class DLinkedList
{
public:
class Node; //forward declaration
protected:
Node* head;
Node* tail;
int count;
public:
DLinkedList() ;
~DLinkedList();
void add(const T& e);
void add(int index, const T& e);
T removeAt(int index);
bool removeItem(const T& removeItem);
bool empty();
int size();
void clear();
T get(int index);
void set(int index, const T& e);
int indexOf(const T& item);
bool contains(const T& item);
};

For example:

Test Result

Stack<int> stack; 10
cout << stack.empty() << " " << stack.size();

Stack<int> stack; 8

int item[] = { 3, 1, 4, 5, 2, 8, 10, 12 };


for (int idx = 0; idx < 8; idx++) stack.push(item[idx]);

assert(stack.top() == 12);

stack.pop();
stack.pop();

cout << stack.top();

void push(T item) {

// TODO: Push new element into the top of the stack

this->list.add(0, item);

T pop() {

// TODO: Remove an element on top of the stack

return this->list.removeAt(0);

T top() {

// TODO: Get value of the element on top of the stack

return this->list.get(0);
}

bool empty() {

// TODO: Determine if the stack is empty

return this->list.empty();

int size() {

// TODO: Get the size of the stack

return this->list.size();

void clear() {

// TODO: Clear all elements of the stack

this->list.clear();
}
Test Expected Got

Stack<int> stack; 10 10
cout << stack.empty() << " " << stack.size();

Stack<int> stack; 8 8

int item[] = { 3, 1, 4, 5, 2, 8, 10, 12 };


for (int idx = 0; idx < 8; idx++) stack.push(item[idx]);

assert(stack.top() == 12);

stack.pop();
stack.pop();

cout << stack.top();

EX7:
Given a string S of characters, a duplicate removal consists of choosing two adjacent and equal
letters, and removing them.

We repeatedly make duplicate removals on S until we no longer can.

Return the final string after all such duplicate removals have been made.

For example:
Test Result

cout << removeDuplicates("abbaca"); ca

cout << removeDuplicates("aab"); b

template <class T>


class _Stack{
public:
class Node;
private:
Node* head;
Node* tail;
int count = 0;
public:
void push(const T &e);
int pop();
T top();
bool isEmpty();
int size();
public:
class Node{
private:
Node* next;
T data;
friend class _Stack;
public:
Node(){
next = 0;
}
Node(Node* next){
this->next = next;
}
Node(T data, Node* next){
this->data = data;
this->next = next;
}
};
};

template <class T>


void _Stack<T>::push(const T &e){
Node *pNew = new Node(e,nullptr);
if (this->count == 0)
this->tail = pNew;
else
pNew->next = this->head;
this->head = pNew;
this->count++;
}
template <class T>
int _Stack<T>::pop(){
Node* dltPtr = this->head;
if (this->count == 0 ) return 0;
if (this->count == 1){
this->head = nullptr;
this->tail = nullptr;
}
this->head = dltPtr->next;
delete dltPtr;
this->count--;
return 1;
}
template <class T>
T _Stack<T>::top(){
if (this->count == 0) return 0;
return this->head->data;
}
template <class T>
bool _Stack<T>::isEmpty(){
if (this->count == 0) return true;
else return false;
}
template <class T>
int _Stack<T>::size(){
return this->count;
}
string removeDuplicates(string S){
/*TODO*/
_Stack<char> container;
for (size_t i=0; i<S.length(); i++){
if (container.isEmpty())
container.push(S[i]);
else{
char top = container.top();
if (top == S[i])
container.pop();
if (top != S[i])
container.push(S[i]);
}
}
string res = "";
while (container.size() != 0){
res += container.top();
container.pop();
}
char temp;
for (size_t i=0; i<res.length()/2; i++){
temp = res[i];
res[i] = res[res.length()-i-1];
res[res.length()-i-1] = temp;
}
return res;
}

EX8:
Given a string s containing just the characters '(', ')', '[', ']', '{', and '}'. Check if the input string is
valid based on following rules:

1. Open brackets must be closed by the same type of brackets.


2. Open brackets must be closed in the correct order.

For example:

• String "[]()" is a valid string, also "[()]".


• String "[])" is not a valid string.

Your task is to implement the function


bool isValidParentheses (string s){
/*TODO*/
}
For example:

Test Result

cout << isValidParentheses("[]"); 1

cout << isValidParentheses("[]()"); 1

cout << isValidParentheses("[)"); 0

template <class T>

class _Stack{

public:

class Node;

private:

Node* head;

int count = 0;

public:

void push(const T &c);


int pop();

T top();

bool isEmpty();

public:

class Node{

private:

T data;

Node* next;

friend class _Stack<T>;

public:

Node() {

next = 0;

Node(Node* next) {

this->next = next;

Node(T data, Node* next) {

this->data = data;

this->next = next;

};

};

template <class T>

void _Stack<T>::push(const T &c){

Node* pNew = new Node(c,nullptr);

pNew->next = this->head;

this->head = pNew;

this->count++;

template <class T>


int _Stack<T>::pop(){

if (this->count == 0) return 0;

Node* dltPtr = this->head;

this->head = dltPtr->next;

this->count--;

delete dltPtr;

return 1;

template <class T>

T _Stack<T>::top(){

if (this->count == 0) return 0;

T dataOut = this->head->data;

return dataOut;

template <class T>

bool _Stack<T>::isEmpty(){

if (this->count == 0) return true;

else return false;

bool isValidParentheses (string str){

_Stack<char> parent;

for (size_t i=0; i<str.length(); i++){

if (str[i] == '(' || str[i] == '[' || str[i] == '{'){

parent.push(str[i]);

if (str[i] == ')' || str[i] == ']' || str[i] == '}'){

if (parent.isEmpty())

return false;

char top = parent.top();

if ((top == '(' && str[i] == ')') || (top == '[' && str[i] == ']') || (top == '{' && str[i] == '}')){
parent.pop();

else

return false;

return parent.isEmpty();

EX9:
Implement method bubbleSort() in class SLinkedList to sort this list in ascending order. After each
bubble, we will print out a list to check (using printList).
#include <iostream>

#include <sstream>

using namespace std;

template <class T>

class SLinkedList {

public:

class Node; // Forward declaration

protected:

Node* head;

Node* tail;

int count;

public:

SLinkedList()

this->head = nullptr;

this->tail = nullptr;

this->count = 0;
}

~SLinkedList(){};

void add(T e)

Node *pNew = new Node(e);

if (this->count == 0)

this->head = this->tail = pNew;

else

this->tail->next = pNew;

this->tail = pNew;

this->count++;

int size()

return this->count;

void printList()

stringstream ss;

ss << "[";

Node *ptr = head;

while (ptr != tail)

{
ss << ptr->data << ",";

ptr = ptr->next;

if (count > 0)

ss << ptr->data << "]";

else

ss << "]";

cout << ss.str() << endl;

public:

class Node {

private:

T data;

Node* next;

friend class SLinkedList<T>;

public:

Node() {

next = 0;

Node(T data) {

this->data = data;

this->next = nullptr;

};

void bubbleSort();

};
For example:

Test Result

int arr[] = {9, 2, 8, 4, 1}; [2,8,4,1,9]


SLinkedList<int> list; [2,4,1,8,9]
for(int i = 0; i <int(sizeof(arr))/4;i++) [2,1,4,8,9]
list.add(arr[i]); [1,2,4,8,9]
list.bubbleSort();

void swapData(int &a, int &b){


int temp = a;
a = b;
b = temp;
}
template <class T>
void SLinkedList<T>::bubbleSort(){
Node* current = this->tail;
bool flag = false;
while (current != this->head && flag == false){
Node* walker = this->head;
flag = true;
while (walker != current){
if (walker->data > walker->next->data){
flag = false;
swap (walker->data, walker->next->data);
}
walker = walker->next;
}
this->printList();
Node* preCurr = this->head;
while (preCurr->next != current){
preCurr = preCurr->next;
}
current = preCurr;
}
}
Test Expected Got

int arr[] = {9, 2, 8, 4, 1}; [2,8,4,1,9] [2,8,4,1,9]


SLinkedList<int> list; [2,4,1,8,9] [2,4,1,8,9]
for(int i = 0; i <int(sizeof(arr))/4;i++) [2,1,4,8,9] [2,1,4,8,9]
list.add(arr[i]); [1,2,4,8,9] [1,2,4,8,9]
list.bubbleSort();
Your code failed one or more hidden tests.
EX10:
Two strings are called permutation of each other when they have exactly the same number of
character, and the number of appearance of each character in each string must be the same.
For example:
String a = "abba" and String b = "baba" are said to be permutation of each other. While String a =
"abbc" and String b = "baba" are not.
Your task in this exercise is to implement the isPermutation function. Note that, you can write one
or more functions in order to achieve this exercise.

#ifndef SORTINGAPPLICATION_H
#define SORTINGAPPLICATION_H
#include <iostream>
#include <string>
using namespace std;
bool isPermutation (string a, string b) {}
#endif /* SORTINGAPPLICATION_H */

For example:

Test Result

string a = "abba"; 1
string b="baba";
cout << isPermutation(a, b);

string a = "abbac"; 0
string b="baba";
cout << isPermutation(a, b);

/* Your helping functions go here */


string bubbleSort (string &s){
int L = s.length();
int current = 0;
int walker = 0;
bool flag = false;
while (current < L && flag == false){
walker = L - 1;
flag = true;
while (walker > current){
if(s[walker] < s[walker-1]){
flag = false;
char temp = s[walker];
s[walker] = s[walker-1];
s[walker-1] = temp;
}
walker = walker - 1;
}
current = current + 1;
}
return s;
}
bool isPermutation (string a, string b) {
//TODO
string Ordered_a = bubbleSort(a);
string Ordered_b = bubbleSort(b);
int L1 = Ordered_a.length();
int L2 = Ordered_b.length();
if (L1 != L2) return false;
for (size_t i=0; i<Ordered_a.length(); i++){
if (Ordered_a[i] == Ordered_b[i])
continue;
if (Ordered_a[i] != Ordered_b[i])
return false;
}
return true;
}

Test Expected Got

string a = "abba"; 1 1
string b="baba";
cout << isPermutation(a, b);

string a = "abbac"; 0 0
string b="baba";
cout << isPermutation(a, b);

EX11:
QuickSort is one of the fastest sorting algorithms for sorting large data. When implemented well, it
can be about two or three times faster than its main competitors, such as MergeSort and
HeapSort. When the number of elements is below some threshold (min_size), switch to insertion sort
- non-recursive sorting algorithm that performs fewer swaps, comparisons or other operations on
such small arrays.

Implement static methods hybridQuickSort in class Sorting to sort an array in ascending order. If
you do insertion sort, please print "Insertion sort: array" (using printArray) first. If you do quick sort,
please print "Quick sort: array (using printArray)" first. Please read example carefully to know exactly
what we print.
To match the test cases, please note:

• Using first element as pivot


• Recursively call the hybridQuickSort function to the left of the pivot first, then recursively to
the right of the pivot
• Do insertion sort if sub array size smaller than min_size
#include <iostream>

using namespace std;

template <class T>

class Sorting

private:

static T *Partition(T *start, T *end);

public:

static void printArray(T *start, T *end)

int size = end - start;

for (int i = 0; i < size - 1; i++)

cout << start[i] << ", ";

cout << start[size - 1];

cout << endl;

static void insertionSort(T *start, T *end);

static void hybridQuickSort(T *start, T *end, int min_size);

};

For example:

Test Result

int array[] = {1, 2, 6, 4, 7, 8, 5, 3}; Quick sort: 1, 2, 6, 4, 7, 8, 5, 3


int min_size = 4; Quick sort: 2, 6, 4, 7, 8, 5, 3
Test Result

Sorting<int>::hybridQuickSort(&array[0], &array[8], min_size); Quick sort: 6, 4, 7, 8, 5, 3


Insertion sort: 5, 4, 3
Insertion sort: 8, 7

int array[] = {2, 6, 4, 12, 23, 1, 0, -12}; Quick sort: 2, 6, 4, 12, 23, 1, 0, -12
int min_size = 4; Insertion sort: 1, -12, 0
Sorting<int>::hybridQuickSort(&array[0], &array[8], min_size); Quick sort: 23, 12, 4, 6
Insertion sort: 6, 12, 4

int array[] = {30, 7, 20, 0, -13, 1, 19, 72}; Quick sort: 30, 7, 20, 0, -13, 1, 19, 72
int min_size = 3; Quick sort: 19, 7, 20, 0, -13, 1
Sorting<int>::hybridQuickSort(&array[0], &array[8], min_size); Quick sort: -13, 7, 1, 0
Quick sort: 7, 1, 0
Insertion sort: 0, 1
Insertion sort: 20
Insertion sort: 72

template <class T>

T *Sorting<T>::Partition(T *start, T *end){

cout<<"Quick sort: ";

printArray(start,end);

T pivot = start[0];

int i=0;

int j=end-start;

do{

do{

i = i + 1;

} while(start[i] < pivot);

do{

j = j - 1;

} while(start[j] > pivot);

swap(start[i],start[j]);

} while(i < j);

swap(start[i],start[j]);
swap(start[0], start[j]);

return &start[j];

template <class T>

void Sorting<T>::insertionSort(T *start, T *end){

cout<<"Insertion sort: ";

printArray(start,end);

int count = end - start;

if (count > 1){

int curr = 1;

while (curr < count){

T temp = start[curr];

int walker = curr - 1;

while (walker > 0 && temp < start[walker]){

start[walker+1] = start[walker];

walker = walker - 1;

start[walker+1] = temp;

curr = curr + 1;

template <class T>

void Sorting<T>::hybridQuickSort(T *start, T *end, int min_size){

if (end-start < min_size){

if (end - start > 0){

insertionSort(start, end);

else{
if (end > start){

T* pivot = Partition(start, end);

hybridQuickSort(start, pivot, min_size);

hybridQuickSort(pivot+1,end,min_size);

}
}
Test Expected Got

int array[] = {1, 2, 6, 4, 7, 8, 5, 3}; Quick sort: 1, 2, 6, 4, 7, 8, 5, Quick sort: 1, 2, 6, 4, 7, 8, 5,


int min_size = 4; 3 3
Sorting<int>::hybridQuickSort(&array[0], &array[8], Quick sort: 2, 6, 4, 7, 8, 5, 3 Quick sort: 2, 6, 4, 7, 8, 5, 3
min_size); Quick sort: 6, 4, 7, 8, 5, 3 Quick sort: 6, 4, 7, 8, 5, 3
Insertion sort: 5, 4, 3 Insertion sort: 5, 4, 3
Insertion sort: 8, 7 Insertion sort: 8, 7

int array[] = {2, 6, 4, 12, 23, 1, 0, -12}; Quick sort: 2, 6, 4, 12, 23, 1, Quick sort: 2, 6, 4, 12, 23, 1,
int min_size = 4; 0, -12 0, -12
Sorting<int>::hybridQuickSort(&array[0], &array[8], Insertion sort: 1, -12, 0 Insertion sort: 1, -12, 0
min_size); Quick sort: 23, 12, 4, 6 Quick sort: 23, 12, 4, 6
Insertion sort: 6, 12, 4 Insertion sort: 6, 12, 4

int array[] = {30, 7, 20, 0, -13, 1, 19, 72}; Quick sort: 30, 7, 20, 0, -13, Quick sort: 30, 7, 20, 0, -13,
int min_size = 3; 1, 19, 72 1, 19, 72
Sorting<int>::hybridQuickSort(&array[0], &array[8], Quick sort: 19, 7, 20, 0, -13, 1 Quick sort: 19, 7, 20, 0, -13,
min_size); Quick sort: -13, 7, 1, 0 1
Quick sort: 7, 1, 0 Quick sort: -13, 7, 1, 0
Insertion sort: 0, 1 Quick sort: 7, 1, 0
Insertion sort: 20 Insertion sort: 0, 1
Insertion sort: 72 Insertion sort: 20
Insertion sort: 72
Passed all tests!

EX12:
Implement static methods Merge and MergeSort in class Sorting to sort an array in ascending
order. The Merge method has already been defined a call to method printArray so you do not have
to call this method again to print your array.
#ifndef SORTING_H
#define SORTING_H
#include <iostream>
using namespace std;
template <class T>
class Sorting {
public:
/* Function to print an array */
static void printArray(T *start, T *end)
{
long size = end - start + 1;
for (int i = 0; i < size - 1; i++)
cout << start[i] << ", ";
cout << start[size - 1];
cout << endl;
}

static void merge(T* left, T* middle, T* right){


/*TODO*/
Sorting::printArray(left, right);
}
static void mergeSort(T* start, T* end) {
/*TODO*/
}
};
#endif /* SORTING_H */

For example:

Test Result

int arr[] = {0,2,4,3,1,4}; 0, 2


Sorting<int>::mergeSort(&arr[0], &arr[5]); 0, 2, 4
1, 3
1, 3, 4
0, 1, 2, 3, 4, 4

int arr[] = {1};


Sorting<int>::mergeSort(&arr[0], &arr[0]);

static void merge(T* left, T* middle, T* right){


/*TODO*/
int size1 = middle - left + 1;
int size2 = right - middle;
T* tempArr1 = new T[size1];
T* tempArr2 = new T[size2];
for (int i=0; i<size1; i++)
tempArr1[i]=left[i];
for (int i=0; i<size2; i++)
tempArr2[i]=middle[i+1];
int i=0, j=0, count=0;
while (i<size1 && j<size2){
if (tempArr1[i] < tempArr2[j]){
left[count] = tempArr1[i];
i++;
}
else{
left[count] = tempArr2[j];
j++;
}
count++;
}
while (i<size1){
left[count] = tempArr1[i];
i++;
count++;
}
while (j<size2){
left[count] = tempArr2[j];
j++;
count++;
}
Sorting::printArray(left, &left[size1+size2-1]);
}
static void mergeSort(T* start, T* end){
/*TODO*/
if (start < end){
int midpt = (end - start)/2;
mergeSort(&start[0], &start[midpt]);
mergeSort(&start[midpt+1], &start[end-start]);
merge(start, &start[midpt], end);
}
}

Test Expected Got

int arr[] = {0,2,4,3,1,4}; 0, 2 0, 2


Sorting<int>::mergeSort(&arr[0], &arr[5]); 0, 2, 4 0, 2, 4
1, 3 1, 3
1, 3, 4 1, 3, 4
0, 1, 2, 3, 4, 4 0, 1, 2, 3, 4, 4

int arr[] = {1};


Sorting<int>::mergeSort(&arr[0], &arr[0]);

int arr[] = {1,2,3,4,0}; 1, 2 1, 2


Sorting<int>::mergeSort(&arr[0], &arr[4]); 1, 2, 3 1, 2, 3
0, 4 0, 4
0, 1, 2, 3, 4 0, 1, 2, 3, 4

EX13:
Implement static method oddEvenSort in class Sorting to sort an array in ascending order. After
each selection, we will print out a list to check (using printArray method). Remember to sort even
first.
Remind about odd even sort:

• This algorithm is divided into two phases - odd and even Phase. The algorithm runs until the
array elements are sorted and in each iteration two phases mentioned above occurs.
• In the odd phase, we perform a bubble sort on odd indexed elements and in the even phase,
we perform a bubble sort on even indexed elements.

#include <iostream>

using namespace std;

template <class T>

class Sorting

public:

/* Function to print an array */

static void printArray(T *start, T *end)

int size = end - start;

for (int i = 0; i < size - 1; i++)

cout << start[i] << ", ";

cout << start[size - 1];

cout << endl;

static void oddEvenSort(T *start, T *end);

};

For example:

Test Result

int arr[] = {3, 2, 3, 8, 5, 6, 4, 1}; 2, 3, 3, 5, 8, 1, 6, 4


Sorting<int>::oddEvenSort(&arr[0], &arr[8]); 2, 3, 3, 1, 5, 4, 8, 6
2, 1, 3, 3, 4, 5, 6, 8
1, 2, 3, 3, 4, 5, 6, 8
1, 2, 3, 3, 4, 5, 6, 8

template <class T>

void swap(T *a, T *b){


T temp = *a;

*a = *b;

*b = *temp;

template <class T>

void Sorting<T>::oddEvenSort(T *start, T *end){

/*TODO*/

int size = end - start;

bool flag = false;

while (flag == false){

flag = true;

for (int i=0; i<size; i+=2){

if (start[i]>start[i+1]){

swap (start[i], start[i+1]);

flag = false;

for (int i=1; i<size; i+=2){

if (start[i]>start[i+1]){

swap (start[i], start[i+1]);

flag = false;

Sorting<T>::printArray(start, end);

Test Expected Got

int arr[] = {3, 2, 3, 8, 5, 6, 4, 1}; 2, 3, 3, 5, 8, 1, 6, 4 2, 3, 3, 5, 8, 1, 6, 4


Sorting<int>::oddEvenSort(&arr[0], &arr[8]); 2, 3, 3, 1, 5, 4, 8, 6 2, 3, 3, 1, 5, 4, 8, 6
Test Expected Got

2, 1, 3, 3, 4, 5, 6, 8 2, 1, 3, 3, 4, 5, 6, 8
1, 2, 3, 3, 4, 5, 6, 8 1, 2, 3, 3, 4, 5, 6, 8
1, 2, 3, 3, 4, 5, 6, 8 1, 2, 3, 3, 4, 5, 6, 8

int arr[] = {9, 30, 1, -7, 7, -9, 5, 6,-1,-2}; 9, -7, 30, -9, 1, 5, 7, -2, 6, -1 9, -7, 30, -9, 1, 5, 7, -2, 6, -1
Sorting<int>::oddEvenSort(&arr[0], &arr[10]); -7, -9, 9, 1, 30, -2, 5, -1, 7, 6 -7, -9, 9, 1, 30, -2, 5, -1, 7, 6
-9, -7, 1, -2, 9, -1, 30, 5, 6, 7 -9, -7, 1, -2, 9, -1, 30, 5, 6, 7
-9, -7, -2, -1, 1, 5, 9, 6, 30, 7 -9, -7, -2, -1, 1, 5, 9, 6, 30, 7
-9, -7, -2, -1, 1, 5, 6, 7, 9, 30 -9, -7, -2, -1, 1, 5, 6, 7, 9, 30
-9, -7, -2, -1, 1, 5, 6, 7, 9, 30 -9, -7, -2, -1, 1, 5, 6, 7, 9, 30

EX14:
Implement static methods Partition and QuickSort in class Sorting to sort an array in ascending
order.
#ifndef SORTING_H
#define SORTING_H
#include <sstream>
#include <iostream>
#include <type_traits>
using namespace std;
template <class T>
class Sorting {
private:
static T* Partition(T* start, T* end) ;
public:
static void QuickSort(T* start, T*
end) ;
};
#endif /* SORTING_H */

You can read the pseudocode


of the algorithm used to in
method Partition in the below
image.

For example:

Test Result

int array[] = { 3, 5, 7, 10 ,12, 14, 15, 13, 1, 2, 9, 6, 4, 8, 11, 16, 17, Index of pivots: 2 0 0 6 1 0 2 1 0 0 2 1 0 0 0 0 0 0 1 0
18, 20, 19 }; Array after sorting: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
cout << "Index of pivots: "; 16 17 18 19 20
Sorting<int>::QuickSort(&array[0], &array[20]);
cout << "\n";
cout << "Array after sorting: ";
for (int i : array) cout << i << " ";
static T* Partition(T* start, T* end) {
// TODO: return the pointer which points to the pivot after rearrange the array.
T pivot = start[0];
int i=0;
int j=end-start;
do{
do{
i = i + 1;
} while(start[i] < pivot);

do{
j = j - 1;
} while(start[j] > pivot);

swap(start[i],start[j]);

} while(i < j);


swap(start[i],start[j]);
swap(start[0], start[j]);
return &start[j];
}
static void QuickSort(T* start, T* end) {
// TODO
// In this question, you must print out the index of pivot in subarray after everytime calling method
Partition.
if (start < end){
T* pivot = Partition (start, end);
cout << pivot - start <<' ';
QuickSort(start, pivot);
QuickSort(pivot+1, end);
}
}

EX15:
Implement static methods sortSegment and ShellSort in class Sorting to sort an array in
ascending order.
#ifndef SORTING_H
#define SORTING_H

#include <sstream>
#include <iostream>
#include <type_traits>
using namespace std;

template <class T>


class Sorting {
private:
static void printArray(T* start, T* end)
{
int size = end - start;
for (int i = 0; i < size; i++)
cout << start[i] << " ";
cout << endl;
}

static void sortSegment(T* start, T* end, int segment_idx, int cur_segment_total) ;

public:
static void ShellSort(T* start, T* end, int* num_segment_list, int num_phases) ;
};

#endif /* SORTING_H */
For example:

Test Result

int num_segment_list[] = {1, 3, 5}; 5 segments: 5 4 3 2 1 10 9 8 7 6


int num_phases = 3; 3 segments: 2 1 3 5 4 7 6 8 10 9
int array[] = { 10, 9, 8 , 7 , 6, 5, 4, 3, 2, 1 }; 1 segments: 1 2 3 4 5 6 7 8 9 10

Sorting<int>::ShellSort(&array[0], &array[10], &num_segment_list[0], num_phases);

static void sortSegment(T* start, T* end, int segment_idx, int cur_segment_total) {


// TODO
int current = segment_idx + cur_segment_total;
int count = end - start;
while (current<count){
T temp = start[current];
int walker = current - cur_segment_total;
while (walker >= 0 && temp < start[walker]){
start[walker + cur_segment_total] = start[walker];
walker -= cur_segment_total;
}
start[walker + cur_segment_total] = temp;
current += cur_segment_total;
}

}
static void ShellSort(T* start, T* end, int* num_segment_list, int num_phases) {
// TODO
// Note: You must print out the array after sorting segments to check whether your algorithm is true.
for (int i=num_phases-1; i>=0;i--){
for (int j=0; j<num_segment_list[i]; j++)
sortSegment(start, end, j, num_segment_list[i]);
cout<<num_segment_list[i]<< " segments: ";
printArray(start, end);
}
}
EX16:
Implement static method selectionSort in class Sorting to sort an array in ascending order. After
each selection, we will print out a list to check (using printArray).
#include <iostream>

using namespace std;

template <class T>

class Sorting

public:

/* Function to print an array */

static void printArray(T *start, T *end)

int size = end - start;

for (int i = 0; i < size - 1; i++)

cout << start[i] << ", ";

cout << start[size - 1];

cout << endl;

static void selectionSort(T *start, T *end);

};

For example:

Test Result

int arr[] = {9, 2, 8, 1, 0, -2}; -2, 2, 8, 1, 0, 9


Sorting<int>::selectionSort(&arr[0], &arr[6]); -2, 0, 8, 1, 2, 9
-2, 0, 1, 8, 2, 9
-2, 0, 1, 2, 8, 9
-2, 0, 1, 2, 8, 9

template <class T>


void swap(T *a, T *b){
T temp = *a;
*a = *b;
*b = *temp;
}
template <class T>
void Sorting<T>::selectionSort(T *start, T *end){
int size = end - start;
int current = 0;
while (current < size - 1){
int min = current;
int walker = current + 1;
while (walker < size){
if (start[walker] < start[min]){
min = walker;
}
walker = walker + 1;
}
swap (start[current], start[min]);
Sorting<T>::printArray (start, end);
current = current + 1;
}

Test Expected Got

int arr[] = {9, 2, 8, 1, 0, -2}; -2, 2, 8, 1, 0, 9 -2, 2, 8, 1, 0, 9


Sorting<int>::selectionSort(&arr[0], &arr[6]); -2, 0, 8, 1, 2, 9 -2, 0, 8, 1, 2, 9
-2, 0, 1, 8, 2, 9 -2, 0, 1, 8, 2, 9
-2, 0, 1, 2, 8, 9 -2, 0, 1, 2, 8, 9
-2, 0, 1, 2, 8, 9 -2, 0, 1, 2, 8, 9

You might also like