【数据结构】单链表

单链表

类的定义

#include <iostream>
#include <vector>
#include <set>
using namespace std;

template<typename T>class LinkNode{
private:
    T value;
    LinkNode* next;
public:
    LinkNode(){
        next = NULL;
    }
    LinkNode(T data){
        value = data;
        next = NULL;
    }
    ~LinkNode(){
        next = NULL;
    }

    void setValue(T v){
        value = v;
    }
    void setNext(LinkNode* n){
        next = n;
    }

    LinkNode* getNext(){
        return next;
    }

    T getValue(){
        return value;
    }
};

template<typename T>class LinkList{
private:
    LinkNode<T>* head;
    LinkNode<T>* next;
public:
    LinkList(){
        head = new LinkNode<T>();
    }
    LinkList(LinkNode<T> node){
        head = node;
    }

    ~LinkList(){
        head = NULL;
    }
    
     //获取链表长度
    int getLen();
    
    //在链表尾部插入节点
    void insertTailNode(T data);
    
     //在特定位置插入节点
    void insertMidNode(T data,int pos);
    
    //在链表首部插入节点
    void insertHeadNode(T data);
    
    //删除链表指定位置节点
    void deleteMidNode(int pos);
    
     //返回链表指定位置的节点
    LinkNode<T> *getSpecificNode(int pos);
        
    //删除链表第一个指定值的节点
    void deleteFirstSpecificNode(T data);
        
    //删除链表所有指定值的节点,并返回已删除节点数目
    int deleteAllSpecificNode(T data);
    
     //清空链表
    void clearList();
        
    //链表转置
    void reverseList();
        
    //找到单链表倒数第m个结点,不得求出链表长度,不得对链表进行逆转
    T getReciprocalM(int m);
        
    //单链表是否有环的判断,求出环内节点数目,并返回环的入口节点
    LinkNode<T> * IsCyclic();
    
    //找到链表的中间节点
    LinkNode<T> * findMid();
        
    //链表打印
    void print();
    }

获取链表长度

//获取链表长度
template<typename T> int LinkList<T>::getLen(){
        int len = 0;
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            index = index->getNext();
            len++;
        }
        return len;
    }

在链表尾部插入节点

//在链表尾部插入节点
template<typename T> void LinkList<T>::insertTailNode(T data){
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            index = index->getNext();
        }
        LinkNode<T>* tail = new LinkNode<T>(data);
        if(index==NULL){
            head = tail;
            index = head;
        }
        else{
            index->setNext(tail);
        }
    }

在特定位置插入节点

 //在特定位置插入节点
template<typename T> void LinkList<T>::insertMidNode(T data,int pos){
        if(pos==getLen()+1){
            insertTailNode(data);
            return;
        }
        if(pos<=0||pos>getLen()){
            cout<<"Illegal Position"<<endl;
            return;
        }
        int idx = 0;
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            if(idx==pos-1){
                break;
            }
            index = index->getNext();
            idx++;
        }
        LinkNode<T> *node = new LinkNode<T>(data);
        LinkNode<T> *tmp = index->getNext();
        index->setNext(node);
        index->getNext()->setNext(tmp);
        return;
    }

在链表首部插入节点

//在链表首部插入节点
template<typename T> void LinkList<T>:: insertHeadNode(T data){
        if(head->getNext() == NULL){
            LinkNode<T> node = new LinkNode<T>(data);
            head->setNext(node);
            return;
        }
        LinkNode<T> node = new LinkNode<T>(data);
        LinkNode<T> *tmp = head;
        head->setNext(node);
        head->getNext()->setNext(tmp);
    }

删除链表指定位置节点

//删除链表指定位置节点
template<typename T> void LinkList<T>:: deleteMidNode(int pos){
        if(pos<=0||pos>getLen()){
            cout<<"Illegal Position"<<endl;
            return;
        }
        int idx = 0;
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            if(idx==pos-1){
                break;
            }
            index = index->getNext();
            idx++;
        }
        index->setNext(index->getNext()->getNext());
    }

返回链表指定位置的节点

//返回链表指定位置的节点
template<typename T> LinkNode<T> * LinkList<T>:: getSpecificNode(int pos){
        if(pos<=0||pos>getLen()){
            cout<<"Illegal Position"<<endl;
            return NULL;
        }
        int idx = 0;
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            if(idx==pos-1){
                break;
            }
            index = index->getNext();
            idx++;
        }
        return index->getNext();
    }

删除链表第一个指定值的节点

//删除链表第一个指定值的节点
template<typename T> void LinkList<T>::deleteFirstSpecificNode(T data){
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            if(index->getNext()->getValue() == data){
                index->setNext(index->getNext()->getNext());
                return;
            }
            index = index->getNext();
        }
        cout<<"No such node"<<endl;
    }

删除链表所有指定值的节点,并返回已删除节点数目

//删除链表所有指定值的节点,并返回已删除节点数目
template<typename T> int LinkList<T>::deleteAllSpecificNode(T data){
        LinkNode<T>* index = head;
        int count = 0;
        while(index!=NULL){
            if(index->getNext()->getValue() == data){
                index->setNext(index->getNext()->getNext());
                count++;
            }
            index = index->getNext();
        }
        return count;
    }

清空链表

  //清空链表
template<typename T> void LinkList<T>::clearList(){
        LinkNode<T>* index = head;
        while(index->getNext()!=NULL){
            index = head->getNext();
            head->setNext(index->getNext());
            delete index;//回收所占空间
        }
    }

链表转置

 //链表转置
template<typename T> void LinkList<T>::reverseList(){
        LinkNode<T>* index = head->getNext();
        LinkNode<T>* i1 = head->getNext();
        LinkNode<T>* i2 = head->getNext()->getNext();
        LinkNode<T>* i3 = head->getNext()->getNext()->getNext();
        while(i3!=NULL){
            i2->setNext(i1);
            i1 = i2;
            i2 = i3;
            i3 = i2->getNext();
        }
        i2->setNext(i1);
        index->setNext(NULL);
        head->setNext(i2);
    }

找到单链表倒数第m个结点,不得求出链表长度,不得对链表进行逆转

//找到单链表倒数第m个结点,不得求出链表长度,不得对链表进行逆转
template<typename T> T LinkList<T>::getReciprocalM(int m){
        LinkNode<T>* index = head->getNext();
        LinkNode<T>* im = head->getNext();
        for(int i=0;i<m;i++){
            im = im->getNext();
        }
        while(im!=NULL){
            index = index->getNext();
            im = im->getNext();
        }
        return index->getValue();
    }

单链表是否有环的判断,求出环内节点数目,并返回环的入口节点

 //单链表是否有环的判断,求出环内节点数目,并返回环的入口节点
template<typename T> LinkNode<T> * LinkList<T>::IsCyclic(){
        LinkNode<T> * p = head;
        LinkNode<T> * q = head;
        int count = 1;
        bool flag = false;
        while(q->getNext()!= NULL){
            p = p->getNext();
            q = q->getNext()->getNext();
            if(p==q) {
                flag = true;
                break;
            }
        }
        if(flag == true){
            cout<<"链表有环"<<endl;
            LinkNode<T> * tmp = p->getNext();
            while(tmp != q){
                count++;
                tmp = tmp->getNext();
            }
            cout<<"环长度为"<<count<<endl;
            int length =0;
            p = head;

            while(p!=q){
                p = p->getNext();
                q = q->getNext();
            }
            cout<<"环连接点值为"<<p->getValue()<<endl;
            tmp = p;
            p = head;
            while(p!=tmp){
               length++;
               p = p->getNext();
            }
            length += count-1;
            cout<<"链表长度为"<<length<<endl;
            return tmp;
        }
        return NULL;
    }

找到链表的中间节点

//找到单链表的中间节点
template<typename T> LinkNode<T> * LinkList<T>::findMid(){
    LinkNode<T> * p = head;
    LinkNode<T> * q = head;
    while(q!= NULL&&q->getNext()!=NULL){
        p = p->getNext();
        q = q->getNext()->getNext();
    }  
    return p;
}

链表打印

//链表打印
template<typename T> void LinkList<T>::print(){
        LinkNode<T>* index = head->getNext();
        int len = getLen();
        for(int i=0;i<len;i++){
            cout<<index->getValue()<<"--";
            index = index->getNext();
        }
        cout<<endl;
    }

测试用例

int main() {
    LinkList<char> *ll = new LinkList<char>();
    vector<char> v = {'a','b','c','d','e','f','a'};
    for(int i=0;i<v.size();i++){
        ll->insertTailNode(v[i]);
    }
    ll->print();
    ll->deleteFirstSpecificNode('a');
    ll->print();
    //cout<<ll->deleteAllSpecificNode('a')<<endl;
    //ll->deleteMidNode(2);
    //ll->insertMidNode('a',4);
    //ll->reverseList();
    //ll->print();
    //cout<<ll->getReciprocalM(7);
    //cout<<ll->getSpecificNode(7)->getValue()<<endl;
    //ll->getSpecificNode(7)->setNext(ll->getSpecificNode(1));
    //ll->IsCyclic();
    if(ll->getLen()%2!=0){
        cout<<ll->findMid()->getValue();
    }
    else{
        cout<<ll->findMid()->getValue()<<"  ";
        cout<<ll->findMid()->getNext()->getValue()<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值