问题
Hi I have made a doubly linked list container. For a project I now have to turn the doubly linked list into a square list. What I mean by square list is that the data will be stored in a square. So for example 4 elements would be stored like this:
10 30
20 40
5 elements would be stored like this:
10 30 50
20 40
10 elements would be stored like this:
10 40 70 100
20 50 80
30 60 90
Basically the number of rows or columns cannot exceed the square root of the ceiling of the size of the list. What it is meant to do is if there is a large number of data it can insert or erase that data quickly by traversing the columns until it finds the column that the value would be inserting or deleting and then traversing the list from that point until it finds the proper spot to do the insertion or deletion.
What I am thinking about doing is to have the data stored in the doubly linked list and then have a doubly linked list that represents the columns. So each node in the column list will point to where a node in the row list that should represent a column header. How would I go about implementing this?
Here is my doubly linked list container:
#include <iostream>
using namespace std;
template <typename T>
class doubleLinkList {
typedef typename std::size_t size_type;
private:
struct rowNode {
rowNode* prev;
rowNode* next;
T data;
rowNode() : prev(nullptr), next(nullptr) {}
};
struct columnNode {
columnNode* prev;
columnNode* next;
T data;
columnNode() : prev(nullptr), next(nullptr) {}
};
struct
rowNode* head;
rowNode* tail;
unsigned count = 0;
public:
doubleLinkList();
~doubleLinkList();
void insert(T value);
size_type size() const { return tail - head; }
size_type max_size() { return std::numeric_limits<size_type>::max(); }
bool empty() const { return head == tail; };
};
template <typename T> doubleLinkList<T>::doubleLinkList() {
head = nullptr;
tail = head;
}
template <typename T> doubleLinkList<T>::~doubleLinkList()
{
while (head)
{
rowNode *tmp = head;
head = head->next;
delete tmp;
}
}
template <typename T> void doubleLinkList<T>::insert(T value) {
rowNode *node = new rowNode;
node->data = value;
// Case 1: There are no nodes yet
if (head == nullptr) {
head = node;
tail = head;
++count;
return;
}
// Case 2 - Inserting at the head of the list
if (node->data < head->data)
{
node->next = head;
head = node;
++count;
return;
}
// Case 3 - Inserting at the end of the list
if (node->data >= tail->data)
{
node->prev = tail;
tail->next = node;
tail = node;
++count;
return;
}
// General case - Inserting into the middle
rowNode* probe = head;
while (probe && (node->data >= probe->data))
{
probe = probe->next;
}
if (probe)
{
node->next = probe;
node->prev = probe->prev;
probe->prev->next = node;
probe->prev = node;
++count;
return;
}
return;
}
template <typename T> bool operator == (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
if (lhs.size() != rhs.size())
return false;
auto lhp = lhs.begin();
auto rhp = rhs.begin();
while (lhp != lhs.end()) {
if (*lhp++ != *rhp++)
return false;
}
return true;
}
template <typename T> bool operator < (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
auto lhp = lhs.begin();
auto rhp = rhs.begin();
while (lhp != lhs.end() && rhp != rhs.end()) {
if (*lhp < *rhp)
return true;
if (*lhp > *rhp)
return false;
++lhp;
++rhp;
}
if (lhp == lhs.end() && rhp != rhs.end())
return true;
return false;
}
template <typename T> inline bool operator != (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
return !(lhs == rhs);
}
template <typename T> inline bool operator > (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
return rhs < lhs;
}
template <typename T> inline bool operator <= (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
return !(lhs > rhs);
}
template <typename T> inline bool operator >= (doubleLinkList<T> const& lhs, doubleLinkList<T> const& rhs) {
return !(lhs < rhs);
}
int main() {
doubleLinkList<int> list;
list.insert(10);
list.insert(20);
list.insert(15);
list.insert(25);
}
来源:https://stackoverflow.com/questions/25224602/how-to-turn-my-doubly-linked-list-container-into-a-square-list-container