在学了部分c++之后找了一个小项目来练习,此项目是在不使用STL的前提下创建一个双向列表,并实现增删改查功能。在练习的过程中加深了我对列表的认识,感觉受益良多,所以记录一下,给需要的小伙伴提供一些方便。
//此代码段为创建类对象头文件
#ifndef __DBLIST_H__
#define __DBLIST_H__
#include <list>
using namespace std;
struct dNode // 创建节点
{
int key;
dNode* pre;
dNode* next;
dNode():key(0), pre(NULL), next(NULL) {}
dNode(int nkey) :key(nkey), pre(NULL), next(NULL) {}
};
class Dblist // list对象
{
private:
dNode* head;
dNode* tail;
int len;
public:
Dblist();
Dblist(Dblist& b);
void insertL(dNode &node);
void insertL(int nkey);
void sortL(const int index = 0);
int findL(dNode &node);
bool deleteL(int n);
bool deleteL(dNode &node);
void printNode() const;
~Dblist();
};
#endif
//此代码段为类方法的实现
#include <iostream>
#include "dblist.h"
#include <list>
using namespace std;
Dblist::Dblist()
{
head = NULL;
tail = NULL;
len = 0;
}
Dblist::Dblist(Dblist& b) //复制构造函数
{
len = b.len;
head = new dNode(); //创建一个新的虚节点
tail = head;
dNode* temp = b.head;
for (int i = 0; i < len; ++i)
{
dNode* tp = new dNode(temp->key); //开始复制key
tail->next = tp;
tp->pre = tail;
tail = tp; // 始终把tail置于末位
temp = temp->next; // temp向后移动,开始下一个对象的复制
}
temp = head->next;
delete head;
head = temp;
}
void Dblist::insertL(dNode& node)
{
dNode* tp = new dNode(node.key);
if (tail == NULL)
{
head = tp;
tail = tp;
}
else
{
tail->next = tp;
tp->pre = tail;
tail = tp;
}
++len;
}
void Dblist::insertL(int nkey)
{
dNode tp(nkey);
this -> insertL(tp);
}
void Dblist::sortL(const int index)
{
if (index == 0)
{
while (head != NULL)
{
if (len < 2)
return;
dNode *h, *p, *temp;
h = NULL;
if (h == NULL)
{
h = head;
head = head->next;
h->next = NULL;
h->pre = NULL;
}
else if (h->key > head->key)
{
temp = head;
head = head->next;
temp->next = h;
temp->pre = NULL;
h->pre = temp;
h = temp;
}
else
{
temp = h;
while (temp->next != NULL && temp->next->key < head->key)
{
temp = temp->next;
}
p = temp->next;
temp->next = head;
temp->next->pre = temp;
head = head->next;
temp->next->next = p;
if (p != NULL)
p->pre = temp->next;
}
}
}
else
while (head != NULL)
{
if (len < 2)
return;
dNode* h, * p, * temp;
h = NULL;
if (h == NULL)
{
h = head;
head = head->next;
h->next = NULL;
h->pre = NULL;
}
else if (h->key < head->key)
{
temp = head;
head = head->next;
temp->next = h;
temp->pre = NULL;
h->pre = temp;
h = temp;
}
else
{
temp = h;
while (temp->next != NULL && temp->next->key > head->key)
{
temp = temp->next;
}
p = temp->next;
temp->next = head;
temp->next->pre = temp;
head = head->next;
temp->next->next = p;
if (p != NULL)
p->pre = temp->next;
}
}
}
int Dblist::findL(dNode& node)
{
dNode* temp = head;
for (int i = 0; i < len; ++i)
{
if (temp->key == node.key)
return (i + 1);
temp = temp->next;
}
return 0;
}
bool Dblist::deleteL(int n)
{
dNode tn(n);
if (this->deleteL(tn))
return true;
else
return false;
}
bool Dblist::deleteL(dNode& node)
{
int index = this->findL(node);
dNode* tp;
if (index)
{
if (len == 1)
{
delete head;
head = NULL;
tail = NULL;
--len;
}
else
{
if (index == 1)
{
tp = head->next;
tp->pre = NULL;
delete head;
head = tp;
--len;
}
else if (index == len)
{
tp = tail->pre;
tp->next = NULL;
delete tail;
tail = tp;
--len;
}
else
{
tp = head;
for (int i = 1; i < index; ++i)
{
tp = tp->next;
}
tp->pre->next = tp->next;
tp->next->pre = tp->pre;
delete tp;
--len;
}
}
return true;
}
else
return false;
}
void Dblist::printNode() const
{
dNode* tp = head;
int i = 1;
cout << "node: ";
while (tp != NULL) {
cout << tp->key;
if (i == len)
cout << "\n";
else
cout << "->";
i++;
tp = tp->next;
}
}
Dblist::~Dblist()
{
dNode* st;
while (head != NULL)
{
st = head->next;
delete head;
head = st;
}
}
//此代码段为测试用例
#include<iostream>
#include "dblist.h"
using namespace std;
int main()
{
cout << "测试双向链表: \n";
Dblist dl;
dl.insertL(1);
dl.insertL(4);
dl.insertL(3);
cout << "dlist1:";
dl.printNode();
Dblist dl2(dl);
cout << "dlist2:";
dl2.printNode();
dl2.deleteL(3);
cout << "delete 3,dlist2:";
dl2.printNode();
dl2.insertL(2);
cout << "insert 2,dlist2:";
dl2.printNode();
dl2.deleteL(4);
cout << "delete 4,dlist2:";
dl2.printNode();
dl2.deleteL(1);
cout << "delete 1,dlist2:";
dl2.printNode();
dl.insertL(2);
cout << "dlist1:";
dl.printNode();
dl.sortL();
cout << "dlist1,ascending sort:";
dl.printNode();
cout << "dlist1,descending sort:";
dl.sortL(1);
dl.printNode();
}