c++实现双向链表,类模板双向链表

c++实现双向链表的思想和c很类似,不同的是c++是将实现的函数放在类中,这样就可以由类实例化出对象再调用类中的函数进行添加、删除、查找、插入元素等功能。类模板实现双向链表在最后进行说明和实现,方法依然类似。
c++实现双向链表
#include<iostream>
#include<assert.h>
using namespace std;

typedef int Datatype;
typedef struct Node//链表是由一个个节点组成所以这里单独定义这一类型方便在链表类中使用
{
     Datatype _data;
     struct Node* next;
     struct Node* prev;
}Node,*pNode;

typedef class LinkList
{
private:
     pNode head;
public:
     LinkList()
    {
      head=NULL;
    }

 void pushback(Datatype x)
 {
      pNode p=new Node[sizeof(Node)];
      p->_data=x;
      p->next=NULL;
      if(head==NULL)
     {
        head=p;
        head->prev=NULL;
     }
     else
    {
        pNode cur=head;
        while(cur->next)
       {
           cur=cur->next;
       }
       cur->next=p;
       p->prev=cur;
    }
 }

 void pushfront(Datatype x)
 {
      pNode tmp=new Node[sizeof(Node)];
      if(head==NULL)
     {
        tmp->_data=x;
        head=tmp;
        head->next= NULL;
        head->prev=NULL;
    }
      else
   {
     //我们要在头结点前再插入一个结点,需要先创建一个新的结点,将头结点的值保存在新节点,然后让新节点的下
     //个结点指向头结点的下一个结点,再让新节点的prev指向头结点,这样就将新节点与原来的链表融合了,然后我
     //们将头结点的数据换成x即可。
        tmp->_data=head->_data;
        tmp->next=head->next;
        tmp->prev=head;//
        head->next=tmp;
        head->_data=x;
  }
 }
 void popback()
 {
      if(head!=NULL)
     {
       pNode cur=head;
       pNode pre=NULL;
       while(cur->next)
     {
       pre=cur;
       cur=cur->next;
     }
     delete[] cur;
     cur=NULL;
     pre->next=NULL;//一定要将pre->next置为空,前面一句仅仅是将cur的值置为空,此时pre->next还指向原来的那块空间
  }
 }

 void popfront()
 {
      if(head!=NULL)
     {
        if(head->next==NULL)
       {
          delete[] head;
          head=NULL;
       }
     else
      {
         pNode del=head;
         head=head->next;
         delete[] del;
         del=NULL;//这里将del置为空可以防止它变为野指针
      }
    }
 }

 pNode find(Datatype x)
 {
      if(head==NULL)
    {
      return NULL;
    }
      else
    {
       pNode cur=head;
       while(cur)
      {
         if(x==cur->_data)
        {
          return cur;
        }
         cur=cur->next;
      }
    return NULL;
  }
 }

 void insert(pNode pos,Datatype x)
 {
      assert(pos);//防止pos为空指针
      if(head==NULL)
     {
       return ;
     }
      else
     {
        pNode cur=head;
        if(head==pos)
       {
        pushfront(x);
       }
       else
       {
            while(cur)
          {
             if(cur==pos)
            {
             pNode tmp=new Node[sizeof(Node)];
             tmp->_data=cur->_data;
             tmp->next=cur->next;
             tmp->prev=cur;
             cur->_data=x;
             cur->next=tmp;
             return ;//insert成功后不要忘了直接返回结束函数
            }
            cur=cur->next;
         }
         cout<<"没有找到这个数字"<<endl;
      }
   }
 }

 void erase(pNode pos)//删除指定位置的结点
 {
      assert(pos);
      if(head==NULL)
     {
       return;
     }
     else
    {
        if(pos==head)
       {
         popfront();
       }
       else
      {
         pNode del=head->next;
         pNode pre=head;
         while(del)
        {
           if(del==pos)
           {
               if(del->next!=NULL)
             {
                pre->next=del->next;
                del->next->prev=pre;
                delete[] del;
                del=NULL;
             }
             else
            {
               delete[] del;
               pre->next=NULL;
            }
             return;
          }
         del=del->next;
         pre=pre->next;
      }
   }
  }
 }

 int use_count()//返回链表中结点的数量
 {
      int count=0;
      pNode cur=head;
      while(cur)
     {
       cur=cur->next;
       count++;
     }
     return count;
 }

 void display()//打印链表
 {
      pNode cur=head;
      while(cur!=NULL)
     {
       cout<<cur->_data<<endl;
       cur=cur->next;
     }
 }

 ~LinkList()
 {
      pNode cur=head;
      while(cur!=NULL)
     {
         pNode Next=cur->next;
         delete cur;
         cur=Next;
         if(cur!=NULL)
        {
          Next=Next->next;
        }
         else
           break;
     }
 }
};

void test()
{
     LinkList ls1;
     ls1.pushback(1);
     ls1.pushback(2);
     ls1.pushback(3);
     ls1.pushfront(0);
     ls1.display();
     ls1.popback();
     ls1.display();
     ls1.popfront();
     ls1.display();
     pNode ret=ls1.find(2);
     if(ret==NULL)
    {
      cout<<"没有找到"<<endl;
    }
     else
    {
      cout<<ret->_data<<endl;
    }
    ls1.insert(ret,5);
    ls1.display();
    pNode ret2=ls1.find(2);
    ls1.erase(ret2);
    ls1.display();
    int ret3=ls1.use_count();
    cout<<ret3<<endl;
}

int main()
{
     test();
     getchar();
     return 0;
}
c++实现类模板双向链表
实现方式和双向链表基本一样,这里只是介绍一下template的用法和注意事项
模板是泛型编程的基础,所谓泛型编程就是编写与类型无关的逻辑代码,是一种复用的方式,模板分为模板函数和模板类。
函数模板格式:
 template <class 形参名1, class 形参名2, class 形参名n>
返回类型 函数名(参数列表)
 {...}
模板形参的定义既可以使用class,也可以使用typename,含义是相同的,这里实现时我们用的是typename。
在这里我们先在类的内部定义好函数,具体实现在类外进行,实现方法不再详细解释。
#include<iostream>
#include<assert.h>
using namespace std;

template<typename T>
struct Node
{
     T _data;
     Node<T>* next;
     Node<T>* prev;
};
template<typename T>
class LinkList
{
private:
     Node<T>* head;
public:
     LinkList();
     void pushback(T x);
     void pushfront(T x);
     void popback();
     void popfront();
     Node<T>* find(T x);
     void insert(Node<T>* pos,T x);
     void erase(Node<T>* pos);
     int use_count();
     void display();
     ~LinkList();
};

template<typename T>
LinkList<T>::LinkList()
{
     head=NULL;
}

template<typename T>
LinkList<T>::~LinkList()
{
     Node<T>* cur=head;
     while(cur!=NULL)
    {
       Node<T>* Next=cur->next;
       delete cur;
       cur=Next;
       if(cur!=NULL)
      {
        Next=Next->next;
      }
      else
        break;
   }
}

template<typename T>
void LinkList<T>::pushback(T x)
{
     Node<T>* p=new Node<T>[sizeof(Node<T>)];
     p->_data=x;
     p->next=NULL;
     if(head==NULL)
    {
      head=p;
      head->prev=NULL;
    }
     else
    {
      Node<T>* cur=head;
      while(cur->next)
     {
        cur=cur->next;
     }
     cur->next=p;
     p->prev=cur;
   }
}

template<typename T>
void LinkList<T>::display()
{
     Node<T>* cur=head;
     while(cur!=NULL)
    {
      cout<<cur->_data<<endl;
      cur=cur->next;
    }
}

template<typename T>
void LinkList<T>::pushfront(T x)
{
     Node<T>* tmp=new Node<T>[sizeof(Node<T>)];
     if(head==NULL)
     {
      tmp->_data=x;
      head=tmp;
      head->next= NULL;
      head->prev=NULL;
     }
    else
    {
      tmp->_data=head->_data;
      tmp->next=head->next;
      tmp->prev=head;
      head->next=tmp;
      head->_data=x;
   }
}

template<typename T>
void LinkList<T>::popback()
{
     if(head!=NULL)
    {
      Node<T>* cur=head;
      Node<T>* pre=NULL;
      while(cur->next)
     {
        pre=cur;
        cur=cur->next;
     } 
     delete[] cur;
     cur=NULL;
     pre->next=NULL;//一定要将pre->next置为空,前面一句仅仅是将cur的值置为空,此时pre->next还指向原来的那块空间
  }
}

template<typename T>
void LinkList<T>::popfront()
{
     if(head!=NULL)
    {
       if(head->next==NULL)
      {
        delete[] head;
        head=NULL;
      } 
       else
      {
        Node<T>* del=head;
        head=head->next;
        delete[] del;
        del=NULL;
      }
   }
}

template<typename T>
int LinkList<T>::use_count()
{
     int count=0;
     Node<T>* cur=head;
     while(cur)
   {
      cur=cur->next;
      count++;
   }
   return count;
}

template<typename T>
Node<T>* LinkList<T>::find(T x)
{
     if(head==NULL)
    {
       return NULL;
    }
     else
   {
       Node<T>* cur=head;
       while(cur)
      {
         if(x==cur->_data)
        {
           return cur;
        }
        cur=cur->next;
      }
     return NULL;
  }
}

template<typename T>
void LinkList<T>::insert(Node<T>* pos,T x)
{
      assert(pos);
      if(head==NULL)
     {
        return ;
     }
      else
     {
        pNode cur=head;
        if(head==pos)
       {
          pushfront(x);
       }
        else
       {
          while(cur)
         {
             if(cur==pos)
           {
              Node<T>* tmp=new Node<T>[sizeof(Node<T>)];
              tmp->_data=cur->_data;
              tmp->next=cur->next;
              tmp->prev=cur;
              cur->_data=x;
              cur->next=tmp;
               return ;
            }
        cur=cur->next;
       }
       cout<<"没有找到这个数字"<<endl;
     }
   }
}

template<typename T>
Node<T>* LinkList<T>::find(T x)
{
       if(head==NULL)
     {
        return NULL;
     }
       else
     {
        Node<T>* cur=head;
        while(cur)
       {
          if(x==cur->_data)
         {
            return cur;
         }
        cur=cur->next;
        }
        return NULL;
    }
}

void test()
{
      LinkList<int> ls;
      ls.pushback(1);
      ls.display();
      ls.pushfront(0);
      ls.display();
      ls.popback();
      ls.display();
      ls.popfront();
      ls.display();
      cout<<ls.use_count()<<endl;
      ls.pushback(1);
      ls.pushback(2);
      ls.pushback(3);
      ls.pushback(4);
      ls.display();
      Node<int>* ret=ls.find(2);
      cout<<ret->_data<<endl;
}

int main()
{
      test();
      getchar();
      return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值