重发一遍~
#include <iostream>
#include <cstdlib>
using namespace std;
typedef int ElementType;
//定义节点类
class LNode{
friend class LinkList;//友元,便于链表类访问节点类私有成员
private:
ElementType data;
LNode *_next;
public:
LNode(ElementType e=0,LNode *_ptrNext=NULL):data(e), _next(_ptrNext){}
~LNode(){}
};
//定义链表类
class LinkList{
private:
LNode* _head;//头指针,指向头节点(为空)
public:
LinkList();//构造函数
~LinkList();
bool IsEmpty();//测试该链表是否为空
bool IsLast(LNode *p);//测试当前位置是否为链表的尾部(与函数FindPrevious有关)
LNode *FindDate(ElementType e);//查找数据并返回该结点地址
LNode *FindPrevious(ElementType e);//查找数据的前一个结点地址(用于删除函数)
void Remove(ElementType e);//查找并删除某节点
LNode *FindLocal(int i);//找第i个节点并返回地址
bool ListInsert(int i, ElementType e);//固定位置插入节点(时间复杂度O(n))
bool ListDelete(int i, ElementType &e);//删除第i个节点(时间复杂度O(n)) (e存入被删的节点数据
void PushFront(int n);//头插法 逆序输入数据 时间复杂度O(n)
void PushBack(int n);//尾插法 按链表序输入数据值 时间复杂度O(n)
int GetLength();//表长
void RemoveAll(ElementType e);//删除表中所有的节点
void PrintList();//打印
void PopBack(); //删除尾节点
void popFront();//删除头节点
LinkList Merge(LinkList &LB);//合并有序链表
};
//构造函数 生成头节点,其指针域为空,数据为0
LinkList::LinkList(){
_head = new LNode;
}
//测试该链表是否为空
bool LinkList::IsEmpty(){
return _head->_next==NULL;
}
//测试当前位置是否为链表的尾部
bool LinkList::IsLast(LNode *p){
return p->_next==NULL;
}
//查找数据并返回该结点地址
LNode *LinkList::FindDate(ElementType e){
LNode *p=_head->_next;//指向第一个节点
while(p!=NULL&&p->data!=e){//注意先后顺序
p=p->_next;
}
return p;
/*
if(!IsEmpty()){
LNode *p=_head->_next;
while(p->date!=e&&p->_next){
p=p->_next;
}
if(p->date==e)return p;
else return NULL;
}
else return NULL;
*/
}
//查找数据的前一个结点地址(用于删除函数)
//与FindData()进行对比 如果找不到该数据点 返回的是末端结点 不是空指针
LNode *LinkList::FindPrevious(ElementType e){
LNode *p=_head;
while(p->_next!=NULL&&p->_next->data!=e){
p=p->_next;
}
return p;
}
//查找并删除某节点
void LinkList::Remove(ElementType e){
LNode *p=FindPrevious(e);
if(!IsLast(p)){ //如果找不到该数据点 返回末端结点
LNode *dele=p->_next;
p->_next=dele->_next;
delete dele;
}
}
//找第i个节点并返回地址 时间复杂度O(n)
LNode *LinkList::FindLocal(int i){
LNode *p = _head;
int j;
for(j=0; j<i&&p->_next!=NULL; j++)//j表示当前指针指向第j个元素
p = p->_next;
if(j != i)
return NULL;//如果!=,则遇到空指针,即不存在该节点
else
return p;
}
//固定位置插入节点
//基本操作为:找到线性表中第i-1个结点,创建新结点s,然后修改第i-1个结点和s结点的后继指针。
bool LinkList::ListInsert(int i, ElementType e){
LNode* p = FindLocal(i-1);
if(p) return false;//前一个节点不存在
LNode *s = new LNode(e,p->_next);
p->_next = s;
return true;
}
//删除第i个节点
//基本操作为:找到线性表中第i-1个结点,修改其指向后继的指针。同时用delete
bool LinkList::ListDelete(int i, ElementType &e){
LNode *p = FindLocal(i-1);
if(!p||!p->_next)
return false;
LNode *dele = p->_next;
e = dele->data;
p->_next = dele->_next;
delete dele;
return true;
}
//头插法 逆序输入数据 时间复杂度O(n)
void LinkList::PushFront(int n){
ElementType e;
LNode *p;
for(int i=1;i<=n;i++){
cin >> e;
p = _head->_next;
_head->_next = new LNode(e, p);
}
}
//尾插法 按链表序输入数据值 时间复杂度O(n)
void LinkList::PushBack(int n){
LNode *_tail = _head;
ElementType e;
for(int i=1; i<=n; i++){
cin>>e;
_tail->_next = new LNode(e, NULL);
_tail = _tail->_next;
}
}
//求表长
int LinkList::GetLength(){
LNode *p = _head;//即便是析构了head指针仍有值
int len=0;
while(p->_next){
len++;
p=p->_next;
}
return len;
}
//查找并删除全部节点
void LinkList::RemoveAll(ElementType e){
if(!IsEmpty()){
LNode *p=_head, *dele;
while(p->_next){
if(p->_next->data==e){
dele=p->_next;
p->_next=dele->_next;
delete dele;
}
p=p->_next;
}
}
}
//打印
void LinkList::PrintList(){
LNode *p=_head;
while(p->_next){
cout<<p->_next->data<<" ";
p=p->_next;
}
}
//合并两个有序链表
LinkList LinkList::Merge(LinkList &LB){
LinkList *LC = new LinkList;
LNode *pa = _head->_next;
LNode *pb = LB._head->_next;
LNode *pc = LC->_head;
while(pa&&pb){
if(pa->data < pb->data){
pc->_next=pa;
pa=pa->_next;
pc=pc->_next;
}
else{
pc->_next=pb;
pb=pb->_next;
pc=pc->_next;
}
}
pc=pa?pa:pb?pb:NULL;
_head->_next=NULL;
LB._head->_next=NULL;
return *LC;
}
//删除尾结点
void LinkList::PopBack(){
LNode *p=_head;
if(!IsEmpty()){
while(p->_next->_next!=NULL){
p=p->_next;
}
LNode *dele=p->_next;
p=dele->_next;
delete dele;
}
}
//删除首节点
void LinkList::popFront(){
LNode *p=_head;
if(!IsEmpty()){
LNode *dele=p->_next;
p=dele->_next;
delete dele;
}
}
//析构函数
LinkList::~LinkList(){
LNode *p=_head, *dele;
//头节点也要释放
while(p){
dele = p;
p = p->_next;
delete dele;
}
}
有错误的地方还请大佬们不吝赐教,谢谢!