双向链表的C++实现

代码有什么缺陷和不足,请指正,谢谢!

 上篇《单循环链表》是带表头,这次双向链表去掉表头,其实没什么区别,原理是一样的。

 1.头文件

#ifndef DOUBLECHAIN_H
#define DOUBLECHAIN_H
//不带表头的双向循环链表

#include<iostream>
template<class T>
class chainnode
{
	template<class T>
	friend class doublechain;
public:
	chainnode()   
	{
		next = nullptr;
		last = nullptr;
		data = 0;
	}
	~chainnode()
	{

	}
public:
	T getdata()
	{
		return data;
	}
	chainnode<T>* getnext()
	{
		return next;
	}
	chainnode<T>* getlast()
	{
		return last;
	}
private:
	T data;
	chainnode<T>* next;
	chainnode<T>* last;
};

template<class T>
class doublechain
{
public:
	doublechain()
	{
		first = end = nullptr;
	    length = 0;
	}
	~doublechain()
	{
		chainnode<T>* temp =first->next;
		while (temp != first)
		{
			chainnode<T>* curr = temp;
			temp = temp->next;
			delete curr;
		}
		delete first;
	}

public:
	bool isempty()   
	{
		return first == nullptr;
	}
	chainnode<T>* getfirst()
	{
		return first;
	}

	chainnode<T>* getend()
	{
		return end;
	}

	void deletenode(int pos);
	int  getlength();
	void insertbefore(T dat, int pos);
	void insertafter(T dat, int pos);
	T find(int pos);
	void print_right();
	void print_left();

	void test_out(); //测试程序,输出2遍链表
private:
	chainnode<T>* first; //指向第一个节点
	chainnode<T>* end; //指向最后一个节点
	int length;
};


template<class T>
void doublechain<T>::insertbefore(T dat, int pos)  //在pos位置前面插入一个元素
{
	if (pos< 0 || pos>length)
	{
		std::cout << "输入的位置数错误" << endl;
		exit(1);
	}

	chainnode<T>* now = new chainnode < T >;
	now->data = dat;
	if (first == nullptr)  //如果循环链表为空表
	{
		first = end = now;
		first->next = first->last = end;
		end->next = end->last = first;
		++length;
	}
	else
	{
		chainnode<T>* pp = first;
		for (int i = 1; i < pos - 1 && pp; ++i)
			pp = pp->next;
		if (pp)
		{
			if (pos == 1)
			{
				now->next = first;
				first->last = now;
				end->next = now;
				now->last = end;
				end = now;
			}
			else
			{
				now->next = pp->next;
				pp->next->last = now;
				pp->next = now;
				now->last = pp;
			}
			++length;
		}
	}
}

template<class T>
void doublechain<T>::insertafter(T dat, int pos)
{
	if (pos < 0 || pos>length)
	{
		std::cout << "输入的位置数错误" << endl;
		exit(1);
	}

	chainnode<T>* now = new chainnode < T >;
	now->data = dat;
	if (first == nullptr)
	{
		first = end = now;
		first->next = first->last = end;
		end->next = end->last = first;
		++length;				
	}
	else
	{
		chainnode<T>* pp = first;
		for (int i = 1; i < pos && pp; ++i)
			pp = pp->next;
		if (pp)
		{
			if (pos == length)
			{
				now->next = first;
				first->last = now;
				pp->next = now;
				now->last = pp;
				end = now;
			}
			else
			{
				now->next = pp->next;
				pp->next->last = now;
				pp->next = now;
				now->last = pp;
			}
			++length;
		}
	}
}
template<class T>
T doublechain<T>::find(int pos)
{
	if (first)
	{
		if (pos<0 || pos>length)
		{
			std::cout << "输入的位置数错误" << endl;
			exit(1);
		}
		chainnode<T>* curr = first;
		for (int i = 1; i < pos&&curr; ++i)
			curr = curr->next;
		return curr->data;
	}
}
template<class T>
int doublechain<T>::getlength()
{
	if (first == nullptr)
		return  0;
	chainnode<T>* current = first->next;
	int len = 1; //包括first节点了
	while (current!=first)
	{
		++len;
		current = current->next;
	}
	length = len;
	return len;
}

template<class T>
void doublechain<T>::deletenode(int pos)
{
	if (first)
	{
		if (pos<0 || pos>length)
		{
			std::cout << "输入的位置数错误" << endl;
			exit(1);
		}
		if (pos == 1)
		{
			chainnode<T>* temp = first;
			end->next = first->next;
			first->next->last = end;
			first = first->next;
			delete temp;
			--length;
		}
		else
		{
			chainnode<T>* tem = first;
			for (int i = 1; i < pos - 1 && tem; ++i) //获得pos前一个元素的地址
				tem = tem->next;
			if (tem &&tem->next)   //确保第pos个元素存在
			{
				chainnode<T>* curr = tem->next; //curr是pos位置元素的地址
				if (pos == length)
				{
					end = tem;
					tem->next = curr->next;
					curr->next->last = tem;
					delete curr;
					--length;
				}
				else
				{
					tem->next = curr->next;
					curr->next->last = tem;
					delete curr;
					--length;
				}
			}
		}
	}
}
template<class T>
void doublechain<T>::print_right()  //正向输出
{
	if (first)
	{
		chainnode<T>* cc = first->next;
		std::cout << first->getdata()<<" ";
		while (cc != first)
		{
			std::cout << cc->getdata()<<" ";
			cc = cc->next;
		}
		std::cout << std::endl;
	}
}

template<class T>
void doublechain<T>::print_left() //反向输出
{
	if (end)
	{
		chainnode<T>* cc = end->last;
		std::cout << end->getdata()<<" ";
		while (cc != end)
		{
			std::cout << cc->getdata()<<" ";
			cc = cc->last;
		}
		std::cout << std::endl;
	}
}

template<class T>
void doublechain<T>::test_out()  //测试程序,检测是否为循环链表
{
	if (first)
	{
		chainnode<T>* cc = first;
		for (int i = 0; i < 2 * length;++i)
		{
		  std::cout << cc->getdata() << " ";
			cc = cc->next;
		}
		std::cout << std::endl;
	}
}
#endif

2.main文件

#include<iostream>
#include"doublechain.h"
using namespace std;

int main()
{
	doublechain<char> liner;
	liner.insertafter('A', 0);
	liner.insertafter('B', 1);
	liner.insertafter('C', 2);
	liner.insertafter('D', 3);
	liner.insertafter('E', 4);
	liner.deletenode(5);

	liner.test_out(); //测试程序,检测双向循环链表是否循环
	liner.print_right();
	liner.print_left();
	system("pause");
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值