[记录] 数据结构----单链表的实现

重发一遍~

#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;
    }
}



有错误的地方还请大佬们不吝赐教,谢谢!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值