这个数据结构是我在做游戏的时候想到的,在对游戏中的图面数据进行处理的时候,想要提高对数据处理的速度,于是就诞生了这个数据结构,用来模拟抽屉式的形式,对数据进行存放和处理。
参考如上的结构图,这个为梯型二维双向链表的结构,因为层层递进,每一层都可以存放不同数量的数据。并且批次之间是有关联的,类似抽屉,因此得此命名。
此结构有几个基本的名称,主链表(Main List),次链表(Subordinate List),节点(Node),标签(ID),主指针(main_pre, main_next),次指针(sub_pre, sub_next)。
主链表(Main List):即最左边的那一列链表,相当于是一个头节点。每一个主链表的node都有一个ID号,用来查询搜索。因为所有的操作都是基于找到对应的主链表上的node,然后再进行的。
次链表(Subordinate List):每一个主链表后面接着的就是次级链表,次级链表没有ID号。
下面是代码展示
#pragma once
#include"iostream"
#include"cstring"
#define ElemType int
using namespace std;
struct DListNode
{
string ID;
ElemType data;
struct DListNode* main_pre;
struct DListNode* main_next;
struct DListNode* sub_pre;
struct DListNode* sub_next;
DListNode(const string& id)
:ID(id)
{}
};
class DrawerList
{
private:
DListNode* phead;
public:
DrawerList();
//basic function
bool CompatrStr(string str1, string str2);
void ShowAll();
int CalculationNumber(); // count how many datas are in the list including the main list
//main list function
/*
every main list node has one ID so that you can insert the node in the subordinate list
when you want to insert the subordinate node, you should deliver the ID to find the poistion
first. And only main list node has ID.
*/
void MainListPrint();
void MainListPushBack(ElemType pushback_value,string ID);
void MainListPopBack();
void MainListPushFront(ElemType pushfront_value,string ID);
void MainListPopFront();
void MainListInsert(ElemType insert_value, string ID, int position);
void ExchangeListNode(string ID1, string ID2); // this function is used to change two main_node
void ShowID();
//subordinate list function
void SubListPrint(string ID);
void SubListPushBack(ElemType pushback_value, string ID);
void SubListPopBack(string ID);
void SubListPushFront(ElemType pushfront_value, string ID);
void SubListPopFront(string ID);
void SubListInsert(ElemType insert_value, string ID, int position);
};
DrawerList::DrawerList()
{
phead = (DListNode*)malloc(sizeof(DListNode));
//phead = new DListNode(ID);
phead->main_next = phead;
phead->main_pre = phead;
phead->sub_next = phead;
phead->sub_pre = phead;
}
//basic function
bool DrawerList::CompatrStr(string str1, string str2)
{
int len1 = str1.length();
int len2 = str2.length();
if (len1 != len2)
{
return false;
}
int len = len1;
string* ptr1 = &str1;
string* ptr2 = &str2;
for (int i = 0; i < len; i++)
{
if (*ptr1 != *ptr2)
{
return false;
}
ptr1++;
ptr2++;
}
return true;
}
void DrawerList::ShowAll()
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
DListNode* tmp = cur->sub_next;
cout << cur->ID << "("<<cur->data<<")" << ":";
if (cur->sub_next == cur)
{
cout << "null";
}
while (tmp != cur)
{
cout << cur->data << " ";
tmp = tmp->sub_next;
}
cur = cur->main_next;
cout << endl;
}
}
int DrawerList::CalculationNumber()
{
int count = 0;
DListNode* cur = phead->main_next;
while (cur != phead)
{
DListNode* tmp = cur->sub_next;
while (tmp != cur)
{
count++;
tmp = tmp->sub_next;
}
count++;
cur = cur->main_next;
}
return count;
}
//main list function
void DrawerList::MainListPushBack(ElemType pushback_value, string ID)
{
//DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
DListNode* newnode = new DListNode(ID);
DListNode* tail = phead->main_pre;
newnode->data = pushback_value;
newnode->sub_next = newnode;
newnode->sub_pre = newnode;
newnode->ID = ID;
tail->main_next = newnode;
newnode->main_pre = tail;
newnode->main_next = phead;
phead->main_pre = newnode;
}
void DrawerList::MainListPrint()
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
cout << cur->data<<" ";
cur = cur->main_next;
}
cout << endl;
}
void DrawerList::MainListPopBack()
{
DListNode* tail = phead->main_pre;
DListNode* pre_tail = tail->main_pre;
pre_tail->main_next = phead;
phead->main_pre = pre_tail;
delete tail;
}
void DrawerList::MainListPushFront(ElemType pushfront_value, string ID)
{
DListNode* next_phead = phead->main_next;
DListNode* newnode = new DListNode(ID);
newnode->ID = ID;
newnode->data = pushfront_value;
newnode->sub_next = newnode;
newnode->sub_pre = newnode;
newnode->main_next = next_phead;
next_phead->main_pre = newnode;
newnode->main_pre = phead;
phead->main_next = newnode;
}
void DrawerList::MainListPopFront()
{
DListNode* next_phead = phead->main_next;
DListNode* next_next_phead = next_phead->main_next;
phead->main_next = next_next_phead;
next_next_phead->main_pre = phead;
delete next_phead;
}
void DrawerList::MainListInsert(ElemType insert_value, string ID, int position)
{
DListNode* cur = phead->main_next;
for (int i = 0; i < position -2; i++)
{
cur = cur->main_next;
if (cur == phead)
{
cout << "null";
break;
}
}
DListNode* next_cur = cur->main_next;
DListNode* newnode = new DListNode(ID);
newnode->ID = ID;
newnode->data = insert_value;
newnode->sub_next = newnode;
newnode->sub_pre = newnode;
cur->main_next = newnode;
newnode->main_pre = cur;
newnode->main_next = next_cur;
next_cur->main_pre = newnode;
}
void DrawerList::ShowID()
{
DListNode* cur = phead->main_next;
cout << "ID:";
while (cur != phead)
{
cout << cur->ID<<" ";
cur = cur->main_next;
}
cout << endl;
}
void DrawerList::ExchangeListNode(string ID1, string ID2)
{
//to find
DListNode* cur = phead->main_next;
DListNode* change1 = nullptr;
DListNode* change2 = nullptr;
int count = 0;
while (cur != phead||count!=2)
{
if (CompareStr(cur->ID, ID1))
{
change1 = cur;
count++;
}
if (CompareStr(cur->ID, ID2))
{
change2 = cur;
count++;
}
cur = cur->main_next;
}
if (count != 2)
{
return;
}
DListNode* change1_pre = change1->main_pre;
DListNode* change1_next = change1->main_next;
DListNode* change2_pre = change2->main_pre;
DListNode* change2_next = change2->main_next;
change1_pre->main_next = change2;
change2->main_pre = change1_pre;
change2->main_next = change1_next;
change1_next->main_pre = change2;
change2_pre->main_next = change1;
change1->main_pre = change2_pre;
change2_next->main_pre = change1;
change1->main_next = change2_next;
}
//subordinate node function
void DrawerList::SubListPrint(string ID)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID) == true)
{
DListNode* sub_cur = cur->sub_next;
cout << ID << ":";
while (sub_cur != cur)
{
cout << sub_cur->data << " ";
sub_cur = sub_cur->sub_next;
}
cout << endl;
break;
}
cur = cur->main_next;
}
}
void DrawerList::SubListPushBack(ElemType pushback_value, string ID)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID) == true)
{
DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
newnode->data = pushback_value;
newnode->main_next = newnode;
newnode->main_pre = newnode;
DListNode* sub_tail = cur->sub_pre;
sub_tail->sub_next = newnode;
newnode->sub_pre = sub_tail;
newnode->sub_next = cur;
cur->sub_pre = newnode;
}
cur = cur->main_next;
}
}
void DrawerList::SubListPopBack(string ID)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID) == true)
{
DListNode* sub_tail = cur->sub_pre;
DListNode* sub_pre_tail = sub_tail->sub_pre;
sub_pre_tail->sub_next = cur;
cur->sub_pre = sub_pre_tail;
free(sub_tail);
break;
}
cur = cur->main_next;
}
}
void DrawerList::SubListPushFront(ElemType pushfront_value, string ID)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID))
{
DListNode* next_phead = cur->sub_next;
DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
newnode->main_next = newnode;
newnode->main_pre = newnode;
newnode->data = pushfront_value;
newnode->sub_pre = cur;
cur->sub_next = newnode;
newnode->sub_next = next_phead;
next_phead->sub_pre = newnode;
break;
}
cur = cur->main_next;
}
}
void DrawerList::SubListPopFront(string ID)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID))
{
DListNode* next_cur = cur->sub_next;
DListNode* next_next_cur = next_cur->sub_next;
cur->sub_next = next_next_cur;
next_next_cur->sub_pre = cur;
free(next_cur);
break;
}
cur = cur->main_next;
}
}
void DrawerList::SubListInsert(ElemType insert_value, string ID, int position)
{
DListNode* cur = phead->main_next;
while (cur != phead)
{
if (CompareStr(cur->ID, ID))
{
for (int i = 0; i < position - 2; i++)
{
cur = cur->sub_next;
}
DListNode* newnode = (DListNode*)malloc(sizeof(DListNode));
newnode->main_next = newnode;
newnode->main_pre = newnode;
newnode->data = insert_value;
DListNode* pre_cur = cur->sub_pre;
pre_cur->sub_next = newnode;
newnode->sub_pre = pre_cur;
newnode->sub_next = cur;
cur->sub_pre = newnode;
break;
}
cur = cur->main_next;
if (cur == phead);
{
cout << "null";
}
}
}