static linked list(homework)

Introduction

Implement a class named static linked list which is based on an fiexed length array storage and figure out the logic inside this.

1、https://en.wikipedia.org/wiki/Linked_list#Linked_lists_using_arrays_of_nodes
2、What’s more, if your code has the request of Google style ,you can click on the website http://clang.llvm.org/docs/ClangFormat.html to learn how to repair automatically.

Ok, now let us to learn how to code a static linked list.Here I have give the main.cpp and list.hpp(it would be a little long), and what we to do is to finish the list.cpp.
/* main.cpp*/
#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.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;
        }
        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_
/*list.cpp*/
#include "list.hpp"
#include <string>
#include <sstream>
#include <assert.h>

list::list() { this->clear(); }

list::list(const list& another) { *(this) = another; }

list::~list() {}

list& list::operator=(const list& another) {
  this->clear();
  for (int i = 0; i < MAX_STORAGE; i++) {
    storage[i] = another.storage[i];
  }
  this->head = another.head;
  this->empty_head = another.empty_head;
  this->_size = another._size;
  return *(this);
}

bool list::empty(void) const { return this->_size == 0; }

list::size_type list::size(void) const { return this->_size; }

std::string list::toString(void) const {
  pointer p = this->head;
  std::string ret;
  while (p != nullpointer) {
    std::stringstream ss;
    ss << this->storage[p].data;
    ret += ss.str();
    ret += "->";
    p = this->storage[p].next;
  }
  ret += "NULL";
  return ret;
}

void list::insert(int position, const int& data) {
  if (position >= 0 && position <= this->_size) {
    if (this->_size + 1 <= MAX_STORAGE) {
      pointer freeNode = empty_head;
      empty_head = storage[empty_head].next;
      storage[freeNode].data = data;
      if (position == 0) {
        storage[freeNode].next = head;
        head = freeNode;
      } else {
        pointer p = head;
        for (int i = 0; i < position - 1; i++) {
          p = storage[p].next;
        }
        storage[freeNode].next = storage[p].next;
        storage[p].next = freeNode;
      }
      this->_size++;
    }
  }
}

void list::erase(int position) {
  if (position >= 0 && position < this->_size) {
    if (position == 0) {
      pointer temp = head;
      head = storage[head].next;
      storage[temp].next = empty_head;
      empty_head = temp;
    } else {
      pointer p = head;
      for (int i = 0; i < position - 1; i++) {
        p = storage[p].next;
      }
      pointer temp = storage[p].next;
      assert(storage[p].next != nullpointer);
      storage[p].next = storage[storage[p].next].next;
      storage[temp].next = empty_head;
      empty_head = temp;
    }
    this->_size--;
  }
}

void list::clear(void) {
  this->head = nullpointer;
  this->_size = 0;
  this->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 (this->head != nullpointer && this->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 = this->head;
        if (storage[head].data > storage[fast].data) {
          storage[slow].next = storage[fast].next;
          storage[fast].next = this->head;
          this->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);
}
Compile error:
1error: ‘stringdoes not name a type

We just add this :

using namespace std;
2error: ‘size_type’ does not name a type

we should take the type list:: before the size_type.

3、In my wrong code,there are concepts about c++ class that I am not clear.Thus I get many Compile errors.

First, typedef int pointer; means pointer is a type of int ,not a pointer. So I shouldn’t use empty_head->nextto get the next data, and I can use the array to get.

Second, node* p means p is a pointer which its type is node, in here pointer is a type of int,when their type is distinct, if we convert one to another, then will occur Compile error,like this error: invalid conversion from ‘list::pointer’ to ‘list::node*’

For example:

error: base operand of ‘->’ is not a pointer
error: NULL used in arithmetic
error: invalid conversion fromlist::pointer’ tolist::node*’

4、About the Header files!!! If you had use stringstreamto convert sth. to string, you must remmember to add the include #include<sstream>

5、If you want to get theData of next location without pointer,you should code like this storage[storage[l].next].data instead of storage[l].next->data or storage[l].next.data

Error answer:
[I] [Test input]
    +---------------------------------------------------------------------
    |5
    |0 6 0 7 0 8 0 9 0 3
    |2
    |3 1
    |5 6
    +---------------------------------------------------------------------


     [Incorrect stdout output]
     Your program's stdout output:
    +---------------------------------------------------------------------
001 |3->NULL size: 5
002 |3->NULL size: 5
003 |3->NULL size: 5
004 |3->NULL size: 5
005 |6->NULL
006 |6->NULL
007 |3->NULL
008 |3->NULL
009 |
    +---------------------------------------------------------------------

     Standard answer's stdout output:
    +---------------------------------------------------------------------
001 |3->9->8->7->6->NULL size: 5
002 |3->9->8->7->6->NULL size: 5
003 |3->9->8->7->6->NULL size: 5
004 |3->9->8->7->6->NULL size: 5
005 |6->5->3->8->6->NULL
006 |3->5->6->6->8->NULL
007 |3->6->7->8->9->NULL
008 |3->6->7->8->9->NULL
009 |
    +---------------------------------------------------------------------

Solution: As we know, we want to use array to simulate the list, the location in the array acts for the pointers in the list.Thus in the constructor function we should add the following code:

for (int i = 0; i < MAX_STORAGE - 1; i++) {
    storage[i].next = i + 1;
  }
  storage[MAX_STORAGE - 1].next = nullpointer;
[II][Test input]
    +---------------------------------------------------------------------
    |5
    |0 0 0 1 0 2 0 3 0 4
    |4 
    |0 1 2 3
    |0 1 2 3
    +---------------------------------------------------------------------


     [Incorrect stdout output]
     Your program's stdout output:
    +---------------------------------------------------------------------
001 |4->43->432->4321->43210->NULL size: 5
002 |4->43->432->4321->43210->NULL size: 5
003 |4->43->432->4321->43210->NULL size: 5
004 |4->43->432->4321->43210->NULL size: 5
005 |3->32->321->3210->32103->321031->NULL
006 |1->13->132->1321->13210->NULL
007 |4->43->432->4321->43210->NULL
008 |4->43->432->4321->43210->NULL
009 |
    +---------------------------------------------------------------------

     Standard answer's stdout output:
    +---------------------------------------------------------------------
001 |4->3->2->1->0->NULL size: 5
002 |4->3->2->1->0->NULL size: 5
003 |4->3->2->1->0->NULL size: 5
004 |4->3->2->1->0->NULL size: 5
005 |3->2->1->0->3->1->NULL
006 |0->1->1->2->3->3->NULL
007 |0->1->2->3->4->NULL
008 |0->1->2->3->4->NULL
009 |
    +---------------------------------------------------------------------

     The difference:
    +---------------------------------------------------------------------
    |1,8c1,8
    |< 4->3->2->1->0->NULL size: 5
    |< 4->3->2->1->0->NULL size: 5
    |< 4->3->2->1->0->NULL size: 5
    |< 4->3->2->1->0->NULL size: 5
    |< 3->2->1->0->3->1->NULL
    |< 0->1->1->2->3->3->NULL
    |< 0->1->2->3->4->NULL
    |< 0->1->2->3->4->NULL
    |---
    |> 4->43->432->4321->43210->NULL size: 5
    |> 4->43->432->4321->43210->NULL size: 5
    |> 4->43->432->4321->43210->NULL size: 5
    |> 4->43->432->4321->43210->NULL size: 5
    |> 3->32->321->3210->32103->321031->NULL
    |> 1->13->132->1321->13210->NULL
    |> 4->43->432->4321->43210->NULL
    |> 4->43->432->4321->43210->NULL

    |
    +---------------------------------------------------------------------


Failed Test Case #1

     [Test input]
    +---------------------------------------------------------------------
    |5
    |0 6 0 7 0 8 0 9 0 3
    |2
    |3 1
    |5 6
    +---------------------------------------------------------------------


     [Time limit for your program (1 sec) exceeded]

Failed Test Case #2

     [Test input]
    +---------------------------------------------------------------------
    |5
    |0 12 1 5 2 98 3 44 0 21
    |3
    |0 1 2
    |5 6 7
    +---------------------------------------------------------------------


     [Time limit for your program (1 sec) exceeded]

Failed Test Case #3

     [Test input]
    +---------------------------------------------------------------------
    |1
    |2 3
    |3 
    |1 2 3
    |3 2 1
    +---------------------------------------------------------------------


     [Time limit for your program (1 sec) exceeded]

Failed Test Case #4

     [Test input]
    +---------------------------------------------------------------------
    |0
    |5 
    |1 2 3 4 5
    |1 2 3 4 5
    +---------------------------------------------------------------------


     [Incorrect stdout output]
     Your program's stdout output:
    +---------------------------------------------------------------------
001 |NULL size: 0
002 |NULL size: 0
003 |NULL size: 0
004 |NULL size: 0
005 |5->54->543->5432->54321->NULL
006 |5->54->543->5432->54321->NULL
007 |NULL
008 |NULL
009 |
    +---------------------------------------------------------------------

     Standard answer's stdout output:
    +---------------------------------------------------------------------
001 |NULL size: 0
002 |NULL size: 0
003 |NULL size: 0
004 |NULL size: 0
005 |5->4->3->2->1->NULL
006 |1->2->3->4->5->NULL
007 |NULL
008 |NULL
009 |
    +---------------------------------------------------------------------

     The difference:
    +---------------------------------------------------------------------
    |5,6c5,6
    |< 5->4->3->2->1->NULL
    |< 1->2->3->4->5->NULL
    |---
    |> 5->54->543->5432->54321->NULL
    |> 5->54->543->5432->54321->NULL

    |
    +---------------------------------------------------------------------

Solution: In the toStringfunction ,put the stringstream s;into the while instead of out of while; Notice the sort is from small to large; clear() and the construct function must be careful;

Time limit is the most difficult problems for me,now I still can’t solve if you know how to solve it ,please tell me!!!

My code:
#include<iostream>
#include "list.hpp"
#include<string>
#include<sstream>
using namespace std;
#define MAX_STORAGE 1000

list::list() {
    _size = 0;
    head = nullpointer;
    empty_head = 0;
    for (int i = 0; i < 999; i++) {
        storage[i].next = i+1;
    }
    storage[999].next = nullpointer;
}
list::list(const list& another) {
    head = nullpointer;
    _size = 0;
    *this = another;
}
list& list::operator=(const list&s) {
    if (this != &s) {
        clear();
        empty_head = s.empty_head;
        head = s.head;
        this->_size = s._size;
        for (int i = 0; i < 1000; i++) {
            storage[i] = s.storage[i];
        }
    }
    return *this;
}
list::~list() {
    this->clear();
}

// Capacity
bool list::empty(void) const {
    return this->_size == 0;
}
list::size_type list::size(void) const {
    return this->_size;
}

// output
// list: [1,2,3,4,5]
// output: 1->2->3->4->5->NULL
string list::toString(void) const {
    pointer pos = this->head;
    string r;
    while (pos != nullpointer) {
        stringstream s;
        s << storage[pos].data;
        r += s.str();
        r += "->";
        pos = storage[pos].next;
    }
    r += "NULL";
    return r;
}
void list::insert(int p, const int& data) {
    if (p > this->_size || p < 0) {
        return;
    }
    pointer t = empty_head;
    empty_head = storage[empty_head].next;
    storage[t].data = data;
    if (p == 0) {
        storage[t].next = head;
        head = t;
    } else {
        pointer p = head;
        int c = 0;
        while (c != p-1) {
            p = storage[p].next;
            c++;
        }
        storage[t].next = storage[p].next;
        storage[p].next = t;
    }
    _size++;
}
void list::erase(int p) {
    if (p >= _size || p < 0) {
        return;
    } else if (p == 0) {
        pointer t = head;
        head = storage[head].next;
        storage[t].next = empty_head;
        empty_head = t;
    } else {
        pointer o = head;
        int c = 0;
        while (c != p - 1) {
            c++;
            o = storage[o].next;
        }
        pointer t = storage[o].next;
        storage[o].next = storage[t].next;
        storage[t].data = 0;
        pointer h = empty_head;
        empty_head = t;
        storage[empty_head].next = h;
    }
    _size--;
}
void list::clear(void) {
    pointer p;
    pointer q;
    while (head != nullpointer) {
        p = head;
        storage[p].data = 0;
        q = empty_head;
        head = storage[head].next;
        empty_head = p;
        storage[empty_head].next = q;
    }
    _size = 0;
}
list& list::sort(void) {
    if (head == nullpointer || storage[head].next == nullpointer) {
        return *this;
    }
    pointer t = head;
    pointer p = storage[head].next;
    while (p != nullpointer) {
        if (storage[p].data >= storage[t].data) {
            p = storage[p].next;
            t = storage[t].next;
        } else {
            pointer l = head;
            if (storage[head].data > storage[p].data) {
                storage[t].next = storage[p].next;
                storage[p].next = head;
                head = p;
            } else {
                while (storage[storage[l].next].data <= storage[p].data) {
                    l = storage[l].next;
                }
                storage[t].next = storage[p].next;
                storage[p].next = storage[l].next;
                storage[l].next = p;
            }
            p = storage[t].next;
        }
    }
    return *this;
}
My code's error:
[Test input]
    +---------------------------------------------------------------------
    |5
    |0 12 1 5 2 98 3 44 0 21
    |3
    |0 1 2
    |5 6 7
    +---------------------------------------------------------------------


     [Time limit for your program (1 sec) exceeded]

PS:

/*list.cpp*/
//This the first wrong code I wrote:
#include<iostream>
#include "list.hpp"
#include<string>
#define MAX_STORAGE 1000

list::list() {
    _size = 0;
    head = -1;
    empty_head = 0;
}
list::list(const list& another) {
    *this = another;
}
list& list::operator=(const list&s) {
    if (this != &s) {
        clear();
        empty_head = s.empty_head;
        head = s.head;
        this->_size = s._size;
        for (int i = 0; i < 1000; i++) {
            storage[i] = s.storage[i];
        }
    }
    return *this;
}
list::~list() {
    this->clear();
}

// Capacity
bool list::empty(void) const {
    return this->_size == 0;
}
list::size_type list::size(void) const {
    return this->_size;
}

// output
// list: [1,2,3,4,5]
// output: 1->2->3->4->5->NULL
string list::toString(void) const {
    node* pos = this->head;
    string r;
    stringstream s;
    while (pos != NULL) {
        s << pos->data;
        string t;
        s >> t;
        r += t + "->";
        s.clear();
        pos += pos->next;
    }
    r += "NULL";
    return r;
}

void list::insert(int p, const int& data) {
    if (p > this->_size || p < 0) {
        return;
    } else if (p == 0) {
        node* t = new node(data, head);
        head = t;
    } else {
        node* p = head;
        int c = 1;
        while (c != p) {
            p = p->next;
            c++;
        }
        node* t = new node(data, p->next);
        p->next = t;
    }
    _size++;
}
void list::erase(int p) {
    if (p >= _size || p < 0) {
        return;
    } else if (p == 0) {
        node* t = head;
        head = head->next;
        delete t;
    } else {
        node* o = head;
        int c = 0;
        while (c != p - 1) {
            c++;
            o = o->next;
        }
        node* t = o->next;
        o->next = t->next;
        delete t;
    }
    _size--;
}
void list::clear(void) {
    if (head != NULL) {
        empty_head = head;
        while (empty_head != NULL) {
            node* t = empty_head;
            empty_head = empty_head->next;
            delete t;
        }
        head = NULL;
        empty_head = NULL;
    }
    _size = 0;
}
list& list::sort(void) {
    if (head == NULL || head->next == NULL) {
        return;
    }
    node* t = head;
    node* p = head->next;
    while (p != NULL) {
        if (p->data <= t->data) {
            p = p->next;
            t = t->next;
        } else {
            node *l = head;
            if (head->data < p->data) {
                t->next = p->next;
                p->next = head;
                head = p;
            } else {
                while (l->next->data >= p->data) {
                    l = l->next;
                }
                t->next = p->next;
                p->next = l->next;
                l->next = p;
            }
            p = t->next;
        }
    }
    return *this;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值