不使用STL的前提下创建双向列表并实现增删改查

在学了部分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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值