C++实现简单的双向链表

vs2013下编译运行,实现了双向链表类List 的 构造函数,拷贝构造、析构函数、赋值运算符重载、清空、头插、头删、尾插、尾删、插入、删除、逆序和删除链表中重复的数据值函数等。



直接贴代码:

DuList.h  类声明、定义、成员函数定义。

#pragma once
//双向链表
#include<assert.h>
#include<iostream>
using namespace  std;


typedef int DataType;

struct ListNode
{
	ListNode(DataType& x)
	:_data(x)
	,_prev(NULL)
	, _next(NULL)
	{}
	DataType _data;
	ListNode * _prev;  
	ListNode * _next;	
};

class List
{
public:
	List()
		:_head(NULL)
		, _tail(NULL)
	{}
	List(const List & l)
	{
		ListNode * end = l._tail;
		while (end)
		{
			PushFront(end->_data);
			end = end->_prev;
		}
	}
	~List()
	{
		ListNode * begin = _head;
		while (begin)
		{
			ListNode * tmp = begin;
			begin = begin->_next;
			delete tmp;
		}
	}
	void Clear()  //清空链表
	{
		ListNode * begin = _head;
		while (begin)
		{
			ListNode * tmp = begin;
			begin = begin->_next;
			delete tmp;
		}
		_head=_tail = NULL;  //最终结果
	}
	List& operator=(List &l)
	{
		List tmp(l);
		swap(_head, l._head);
		swap(_tail, l._tail);
		return *this;
		//tmp被析构
	}
	void PushBack(DataType &x)
	{
		ListNode * tmp = new ListNode(x);
		if (_tail == NULL)
		{
			tmp->_next = _tail;
			_head =_tail= tmp;
		}
		else
		{
			_tail->_next = tmp;
			tmp->_prev = _tail;
			_tail = tmp;
		}
	}
	void PopBack()
	{
		if (_head == _tail)
		{
			delete _head;   //NULL也可以
			_head = _tail = NULL;
		}
		else
		{
			ListNode * prev = _tail->_prev;
			delete(_tail);
			_tail = prev;

		}
	}
	void PushFront(DataType & x)
	{
		ListNode * tmp = new ListNode(x);
		if (_head == NULL)
		{
			_head = tmp;
			_tail = tmp;
		}
		else
		{
			tmp->_next = _head;
			tmp->_prev = NULL;
			_head->_prev = tmp;
			_head = tmp;
		}  //可能没完
	}

	void Reverse()
	{
		assert(_head&&_tail);   //逻辑短路
		ListNode * left = _head;
		ListNode * right = _tail;
		while (left!=right && left->_prev!=right)   //限定条件很重要
		{
			swap(left->_data, right->_data);
			left = left->_next;
			right = right->_prev;
		}
	}

	void PopFront()
	{
		assert(_head);
		if (_head == _tail)
		{
			delete _head;
			_head = _tail = NULL;   //防止野指针
		}
		else
		{
			ListNode *tmp = _head;
			_head = _head->_next;
			delete tmp;
		}
	}
	ListNode * Find(DataType & x)
	{
		ListNode * begin = _head;
		while (begin)
		{
			if (begin->_data == x)  //x的类型必须重载了== 运算符
			{
				return begin;
			}
			begin = begin->_next;
		}
		return NULL;   //调用者需要检查结果是否合法
	}
	void Insert(ListNode * pos, DataType x)
	{
		//在结点之后插入
		assert(pos);
		ListNode * tmp = new ListNode(x);
		if (_tail == pos)
		{   //需要考虑_tail
			_tail->_next = tmp;  
			tmp->_prev = _tail;
			_tail = tmp;
		}
		else
		{ 
			tmp->_next = pos->_next;
			tmp->_prev = pos;
			tmp->_next->_prev = tmp;
			pos->_next = tmp;
		}
	}
	void Erase(ListNode* pos)
	{
		if (_head == _tail)
		{
			assert(_head == pos);
			delete _head;
			_head = _tail = NULL;
			return;
		}
		if (pos == _head)
		{
			_head = _head->_next;
			_head->_prev = NULL;   //防止野指针
		}
		else if (pos == _tail)
		{
			_tail = _tail->_prev;
			_tail->_next = NULL;   //防止野指针
		}
		else
		{
			ListNode * prev = pos->_prev;
			ListNode * next = pos->_next;
			prev->_next = next;
			next->_prev = prev;	
		}
		delete pos;
	}
	void Print()
	{
		ListNode * begin=_head;
		while (begin)
		{
			cout << begin->_data<<"->";
			begin = begin->_next;
		}
		cout << "NULL"<<endl;
	}

	void Unique()
	{
		size_t size = 0;
		ListNode * begin = _head;
		while (begin)
		{
			ListNode *it = _head->_next;
			while (it!=begin&&it!=NULL)
			{
				if (begin->_data == it->_data)
				{
					Erase(it);  //删除it保证指针不失效
					break;
				}
				it = it->_next;
			}
			begin = begin->_next;

		}

	}
private:
	ListNode * _head;
	ListNode * _tail;
};

Main.cpp 测试用例

#include"DuList.h"

void Test1()
{
	List l;
	int a = 1;
	l.PushFront(a);
	l.PushFront(++a);
	l.PushFront(++a);
	l.Print();



	List l2(l);
	l2.Print();
}

void Test2()
{
	List L;
	int a = 1;
	int b = 3;
	L.PushFront(a);
	L.Insert(L.Find(a), (DataType)6);

	L.Insert(L.Find(a), (DataType)5);
	L.Insert(L.Find(a), (DataType)4);
	L.Insert(L.Find(a), (DataType)3);
	L.Insert(L.Find(a), (DataType)2);

	L.Print();

	L.Reverse();
	L.Print();
	DataType i = 16;
	L.PushBack(i);
	L.PushBack(i);
	L.Print();
	L.Unique();
	L.Print();
	//List l3;
	//l3.PushBack(i);
	//l3.Print();
	//L = l3;
	//L.Print();
	//l3.Clear();
	//l3.Print();
	//L.Erase(L.Find(b));
	//L.Erase(L.Find(a));
	//int c = 5;
	//L.Erase(L.Find(c));
	//c = 2;
	//L.Erase(L.Find(c));
	//c = 4;
	//L.Erase(L.Find(c));


	//L.Print();

}

void Test3()   //Unique
{
	//List L2;
	//DataType a = 9;
	//L2.PushBack(a);
	//L2.PushBack(a);
	//L2.PushBack(++a);
	//L2.PushBack(++a);
	//L2.PushBack(++a);
	//L2.PushBack(a);
	//L2.PushBack(a);
	//L2.Print();
	//L2.Unique();
	//L2.Print();
	List L3;
	DataType b = 100;
	L3.PushFront(b);
	L3.Print();
	L3.Unique();
	L3.Print();

}


int main()
{
	//Test1();
	//Test2();
	Test3();
	system("pause");
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值