Introduction
Knowledge points: encapsulation, copy constructor, linked list algorithms, debug methods(GDB or IDE or output debug).
In this Lab, again, you are going to implement a class named static linked list which is based on an fiexed length array storage. You need to figure out the logic inside this.
I recommend you to:
Learn the knowledge points mentioned above. Use local compilers to test you program rather than submit your answer to the system time after time. Use local debug tools(GDB is recommended) to debug your code, especially for the memory leak problem. I can tell you that you will meet runtime error problem if you don’t use local debug tools. Make use of your paper and pen to have some sketches because it’s a good way when you meet list.
Knowledge
Linked List
Read the “Linked lists using arrays of nodes” part.
Requirements:
Just read the requirements in “simple list”
Note that there are exactly two “list” in the class list. One is the actual list while another is the list to maintain the empty nodes in the storage array. And we use empty_head as the head node for the latter. The operation of the linked list implies the maintenance of the empty nodes.
Source Author: 叶嘉祺 (已毕业多年老TA,大家怨念不要太深,如有问题欢迎邮件讨论,~么么哒)
main.cpp
//
// main.cpp
// D&A Static Linked List D&A Static Linked List D&A Static Linked List
//
// Created by 邱兆丰 on 16/4/9.
// Copyright © 2016年 邱兆丰. All rights reserved.
//
#include <iostream>
#include <string>
#include "list.hpp"
using std::cin;
using std::cout;
using std::endl;
using std::string;
int main() {
list li;
int n;
cin >> n;
for (int i = 0, data, pos; i < n; i++) {
cin >> pos >> data;
li.insert(pos, data);
}
cout << li.toString() << " size: " << li.size() << endl;
list li2(li);
list li3;
li = li3 = li2 = li;
cout << li.toString() << " size: " << li.size() << endl;
cout << li2.toString() << " size: " << li2.size() << endl;
cout << li3.toString() << " size: " << li3.size() << endl;
int m;
cin >> m;
for (int i = 0, pos; i < m; i++) {
cin >> pos;
li.erase(pos);
}
for (int i = 0, temp; i < m; i++) {
cin >> temp;
li.insert(0, temp);
}
cout << li.toString() << endl;
cout << li.sort().toString() << endl;
cout << li2.sort().toString() << endl;
cout << li3.sort().toString() << endl;
return 0;
}
list.cpp
//
// list.cpp
// D&A Static Linked List D&A Static Linked List D&A Static Linked List
//
// Created by 邱兆丰 on 16/4/9.
// Copyright © 2016年 邱兆丰. All rights reserved.
//
#include "list.hpp"
#include <sstream>
#define newNode(a, da, po) a = empty_head; \
empty_head = storage[empty_head].next; \
storage[a].next = po; \
storage[a].data = da;
// 不能delete 名字为T的指针
#define deleteNode(a) pointer T = empty_head; \
empty_head = a; \
storage[a].next = T; \
storage[a].data = 0;
list::list() {
_size = 0;
head = nullpointer;
empty_head = 0;
for (int i = 0; i < MAX_STORAGE - 1; i++) {
storage[i].next = i + 1;
}
storage[MAX_STORAGE - 1].next = nullpointer;
}
list::list(const list& another) {
_size = 0;
head = nullpointer;
empty_head = 0;
for (int i = 0; i < MAX_STORAGE - 1; i++) {
storage[i].next = i + 1;
}
storage[MAX_STORAGE - 1].next = nullpointer;
*this = another;
}
list& list::operator=(const list& another) {
for (int i = 0; i < MAX_STORAGE; i++) {
storage[i] = another.storage[i];
}
_size = another._size;
head = another.head;
empty_head = another.empty_head;
return *this;
}
list::~list() {
clear();
}
bool list::empty(void) const {
return (_size == 0);
}
list::size_type list::size(void) const {
return _size;
}
std::string list::toString(void) const {
pointer p = head;
std::ostringstream out;
while (p != nullpointer) {
out << storage[p].data << "->";
p = storage[p].next;
}
out << "NULL";
return out.str();
}
void list::insert(int position, const int& data) {
if (position > _size || position < 0 || _size == MAX_STORAGE) {
return;
}
else if (position == 0) {
pointer temp;
newNode(temp, data, head);
head = temp;
} else {
pointer p = head;
int count = position - 1;
while (count--) {
p = storage[p].next;
}
pointer temp;
newNode(temp, data, storage[p].next);
storage[p].next = temp;
}
_size++;
}
void list::erase(int position) {
if (position >= _size || position < 0) {
return;
}
else if (position == 0) {
pointer temp = head;
head = storage[head].next;
deleteNode(temp);
} else {
pointer p = head;
int count = position - 1;
while (count--) {
p = storage[p].next;
}
pointer temp = storage[p].next;
storage[p].next = storage[temp].next;
deleteNode(temp);
}
_size--;
}
void list::clear(void) {
if (head != nullpointer) {
_size = 0;
head = nullpointer;
empty_head = 0;
for (int i = 0; i < MAX_STORAGE - 1; i++) {
storage[i].next = i + 1;
}
storage[MAX_STORAGE - 1].next = nullpointer;
}
}
list& list::sort(void) {
if (head != nullpointer && storage[head].next != nullpointer) {
pointer slow = head;
pointer fast = storage[head].next;
while (fast != nullpointer) {
if (storage[fast].data >= storage[slow].data) {
fast = storage[fast].next;
slow = storage[slow].next;
} else {
pointer pre = head;
if (storage[head].data > storage[fast].data) {
storage[slow].next = storage[fast].next;
storage[fast].next = head;
head = fast;
} else {
while (storage[storage[pre].next].data <= storage[fast].data) {
pre = storage[pre].next;
}
storage[slow].next = storage[fast].next;
storage[fast].next = storage[pre].next;
storage[pre].next = fast;
}
}
fast = storage[slow].next;
}
}
return *this;
}
list.hpp
#ifndef LIST_H_
#define LIST_H_
#include <string>
#define MAX_STORAGE 1000
class list{
typedef int data_type;
typedef int pointer;
typedef unsigned int size_type;
static const pointer nullpointer = -1;
typedef struct node {
data_type data;
pointer next;
node(const node &another) {
this->operator=(another);
}
node& operator=(const node &another) {
this->data = another.data;
this->next = another.next;
return *this;
}
node(data_type data = 0, pointer next = nullpointer) : data(data), next(next) {}
} node;
node storage[MAX_STORAGE];
size_type _size;
pointer head;
pointer empty_head;
public:
list();
list(const list& another);
list& operator=(const list&);
~list();
// Capacity
bool empty(void) const;
size_type size(void) const;
// output
// list: [1,2,3,4,5]
// output: 1->2->3->4->5->NULL
std::string toString(void) const;
void insert(int position, const int& data);
void erase(int position);
void clear(void);
list& sort(void);
};
#endif // !LIST_H_