您的位置:首页 > 编程语言 > C语言/C++

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

2015-12-14 23:19 627 查看
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: