C++实现双链表的基本功能
作者:网络转载 发布时间:[ 2017/3/7 10:46:24 ] 推荐标签:测试开发技术 双链表
双链表:在单链表的每个结点中,再设置一个指向其前驱结点的指针域
线性表的双向链表存储结构:
[cpp] view plain copy print?
typedef struct Node
{
DataType _data;
struct Node *_next;
struct Node *_front;
}Node;
通过双链表的存储结构我们发现双链表可以反向查找结点优于单链表 ,实质上双链表是以空间换取时间,虽然双链表具有可以反向查找数据的优点但是它也存在缺点:在插入和删除一个结点时需要维护两个指针变量,特别是在双链表的插入中指针的指向顺序是不可修改的。
双链表的插入过程:
双链表的删除过程:
C++实现双链表的基本功能:
[cpp] view plain copy print?
typedef int DataType;
class LinkList;
class Node
{
friend LinkList;
friend ostream &operator<<(ostream &os,Node &n);
friend ostream& operator<<(ostream &os,LinkList &list);
public:
Node(DataType x)
:_data(x)
,_next(NULL)
,_front(NULL)
{}
private:
DataType _data;
Node *_next;
Node *_front;
};
ostream &operator<<(ostream &os,Node &n)
{
os<<n._data;
return os;
}
class LinkList
{
friend ostream& operator<<(ostream &os,LinkList &list);
public:
LinkList()
:_head(NULL)
,_tail(NULL)
{}
LinkList(const LinkList &list)
:_head(NULL)
,_tail(NULL)
{
Node *cur=list._head;
while(cur)
{
Node *tmp=new Node(cur->_data);
if(_tail)
{
_tail->_next=tmp;
tmp->_front=_tail;
_tail=tmp;
}
else //空链表
{
_head=tmp;
_tail=tmp;
}
cur=cur->_next;
}
}
~LinkList()
{
Node *cur=_head;
while(cur)
{
Node *del=cur;
cur=cur->_next;
delete del;
del=NULL;
}
}
public:
void PushBack(DataType x)
{
Node *NewNode=new Node(x);
if(_tail)
{
_tail->_next=NewNode;
NewNode->_front=_tail;
_tail=NewNode;
}
else
{
_head=NewNode;
_tail=NewNode;
}
}
void PopBack()
{
if(!_head && !_tail) //空链表
{
cout<<"链表已空不可尾删"<<endl;
return ;
}
else if(_head == _tail) //只有一个节点
{
delete _tail;
_head=NULL;
_tail=NULL;
}
else //至少存在两个节点
{
Node *tmp=_tail;
_tail=tmp->_front;
_tail->_next=NULL;
delete tmp;
tmp=NULL;
}
}
void PushFront(DataType x)
{
Node *NewNode=new Node(x);
if(_head)
{
Node *tmp=_head;
NewNode->_next=tmp;
tmp->_front=NewNode;
}
else
{
_tail=NewNode;
}
_head=NewNode; //更新头
}
void PopFront()
{
if(!_head && !_tail) //空链表
{
cout<<"链表已空不可头删"<<endl;
return ;
}
else if(_head == _tail) //只有一个节点
{
delete _head;
_head=NULL;
_tail=NULL;
}
else //至少存在两个节点
{
Node *del=_head;
_head=del->_next;
_head->_front=NULL;
delete del;
del=NULL;
}
}
Node *FindNum(DataType x)
{
Node *cur=_head;
while(cur)
{
if(cur->_data == x)
return cur;
cur=cur->_next;
}
return NULL;
}
void Insert(Node *pos,DataType x) //在指定位置后插
{
Node *NewNode=new Node(x);
if(pos->_next)
{
NewNode->_front=pos;
NewNode->_next=pos->_next;
pos->_next->_front=NewNode;
pos->_next=NewNode;
}
else //在后一个结点后插,类似PushBack
{
pos->_next=NewNode;
NewNode->_front=pos;
_tail=NewNode; //更新尾
}
}
void Insert(int,Node *pos,DataType x) //在指定位置前插
{
Node *NewNode=new Node(x);
if(pos->_front)
{
NewNode->_next=pos;
pos->_front->_next=NewNode;
NewNode->_front=pos->_front;
pos->_front=NewNode;
}
else //在第一个结点的前插,类似PushFront
{
NewNode->_next=pos;
pos->_front=NewNode;
_head=NewNode; //更新头
}
}
void Remove(DataType &x)
{
Node *pos=this->FindNum(x);
if(pos != NULL)
{
if((!(pos->_front)) && pos->_next) //删除第一个结点
{
Node *tmp=pos->_next;
tmp->_front=NULL;
_head=tmp;
}
else if(pos->_front && (!(pos->_next))) //删除后一个结点
{
Node *tmp=pos->_front;
tmp->_next=NULL;
_tail=tmp;
}
else //删除中间节点
{
Node *front=pos->_front;
Node *next=pos->_next;
next->_front=front;
front->_next=next;
}
delete pos;
pos=NULL;
}
}
void RemoveAll(DataType &x)
{
Node *cur=_head;
Node *ret=this->FindNum(x);
if(ret != _head) //可删除第一个结点不是要删除的元素
{
while(cur)
{
Remove(x);
cur=cur->_next;
}
}
}
void Sort()
{
int flag=1;
Node *cur=_head;
Node *tail=NULL;
while(cur != tail)
{
while(cur->_next != tail)
{
if(cur->_data > cur->_next->_data)
{
DataType tmp=cur->_data;
cur->_data=cur->_next->_data;
cur->_next->_data=tmp;
flag=0;
}
cur=cur->_next;
}
if(flag == 1)
break;
tail=cur;
cur=_head;
}
}
void Erase(Node *pos)
{
if((!(pos->_front)) && pos->_next) //删除第一个结点
{
Node *tmp=pos->_next;
tmp->_front=NULL;
_head=tmp;
}
else if(pos->_front && (!(pos->_next))) //删除后一个结点
{
Node *tmp=pos->_front;
tmp->_next=NULL;
_tail=tmp;
}
else //删除中间节点
{
Node *front=pos->_front;
Node *next=pos->_next;
next->_front=front;
front->_next=next;
}
delete pos;
pos=NULL;
}
private:
Node *_head;
Node *_tail;
};
ostream& operator<<(ostream &os,LinkList &list)
{
Node *cur=list._head;
while(cur)
{
os<<(*cur)<<" ";
cur=cur->_next;
}
return os;
}
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11