单链表

#ifndef  LINKEDLIST_H

#define LINKEDLIST_H

 

#include <iostream>

using namespace std;

 

template<class T>

struct LinkNode        //链表节点类的定义

{

     T data;  //数据域

     LinkNode<T> *link; //链指针域

     LinkNode(LinkNode<T> *ptr = NULL)    //仅初始化指针成员的构造函数

     {

         link = ptr;

     }

     LinkNode(const T &item,LinkNode<T> *ptr = NULL)    //初始化数据与指针成员的构造函数

     {

         data = item;

         link = ptr;

     }

};

 

template<class T>  //单链表类定义

class List

{

public:

     List()

     {

         first = new LinkNode<T>;

     }

     List(const T &x)

     {

         first = new LinkNode<T>(x);

     }

     List(List<T> &L);

     ~List()

     {

         MakeEmpty();

     }

     void MakeEmpty();  //将链表置为空表

     int Length()const; //计算链表的长度

     LinkNode<T> *GetHead()const //返回附加头结点的地址

     {

         return first;

     }

     LinkNode<T> *Search(T x)const;   //搜索含数据x的元素

     LinkNode<T> *Locate(int i)const; //搜索第i个元素的地址

     bool GetData(int i,T &x)const;   //取出第i个元素的值

     bool Insert(int i,T &x);    //在第i个元素后插入x

     bool Remove(int i,T &x);    //删除第i个元素的值,返回该元素的值给x

     void InputFront(T endTag);  //前插法输入建立单链表

     void InputRear(T endTag);   //后插法输入建立单链表

     void Output();     //输出

     void reverse();    //就地逆置

     int GetNumber(LinkNode<T> *address); //根据链表结点地址计算位置

protected:

     LinkNode<T> *first;    //链表的头指针

};

 

//             List类的成员函数的实现            //

 

//复制构造函数

template<class T>

List<T>::List(List<T> &L)

{

     T value;

     LinkNode<T> *srcptr = L.GetHead();   //被复制表的附加头结点地址

     LinkNode<T> *destptr = first = new LinkNode<T>;

     while(srcptr->link  != NULL)

     {

         value = srcptr->link->data;

         destptr->link = new LinkNode<T>(value);

         destptr = destptr->link;

         srcptr = srcptr->link;

     }

     destptr->link = NULL;

}

 

//将链表置为空

template<class T>

void List<T>::MakeEmpty()

{

     LinkNode<T> *current;

     while(first->link != NULL)

     {

         current = first->link;

         first->link = current->link;

         delete current;

     }

}

 

//计算带附加头结点的单链表的长度

template<class T>

int List<T>::Length()const

{

     LinkNode<T> *current = first->link;

     int count=0;

     while(current != NULL)

     {

         ++count;

         current = current->link;

     }

     return count;

}

 

//在表中搜索含数据x的结点,搜索成功时函数返回该结点地址;否则返回NULL

template<class T>

LinkNode<T> *List<T>::Search(T x)const

{

     LinkNode<T> *current = first->link;

     while(current != NULL)

     {

         if(current->data == x)

              break;

         else

              current = current->link;

     }

     return current;

}

 

//定位函数:返回表中第i个元素的地址。若i<0i超出表中结点个数,则返回NULL

template<class T>

LinkNode<T> *List<T>::Locate(int i)const

{

     if(i < 0)

         return NULL;

     LinkNode<T> *current = first;

     int k = 0;

     while(current != NULL && k < i)

     {

         current = current->link;

         k++;

     }

     return current;    //返回第i个结点地址,若返回NULL,则表示i太大

}

 

//取出链表中第i个元素的值

template<class T>

bool List<T>::GetData(int i,T &x)const

{

     if(i <= 0)

         return false; //i值太小

     LinkNode<T> *current = Locate(i);

     if(current == NULL)         //i值太大

         return false;

     else

     {

         x = current->data;

         return true;

     }

}

 

//将新元素x插入在链表中第i个结点之后

template<class T>

bool List<T>::Insert(int i,T &x)

{

     LinkNode<T> *current = Locate(i);

     if(current == NULL)

         return false;

     LinkNode<T> *newNode = new LinkNode<T>(x);

     if(newNode == NULL)

     {

         cerr<<"存储分配错误!"<<endl;

         exit(1);

     }

     newNode->link = current->link;

     current->link = newNode;

     return true;

}

 

//将链表中的第i个元素删除,通过引用型参数x返回该元素的值

template<class T>

bool List<T>::Remove(int i,T &x)

{

     LinkNode<T> *current = Locate(i-1);

     if(current == NULL || current->link == NULL)

         return false;

     LinkNode<T> *del = current->link;    //重新拉链,将被删结点从链中摘下

     current->link = del->link;

     x = del->data;

     delete del;

     return true;

}

 

//单链表的输出函数:将单链表中所有数据按逻辑顺序输出到屏幕上

template<class T>

void List<T>::Output()

{

     LinkNode<T> *current = first->link;

     while(current != NULL)

     {

          cout<<current->data<<endl;

         current = current->link;

     }

}

 

//前插法输入建立单链表

template<class T>

void List<T>::InputFront(T endTag)

{

     LinkNode<T> *newNode;

     T val;

     MakeEmpty();

     cin>>val;

     while (val != endTag)

     {

         newNode = new LinkNode<T>(val);

         if (newNode == NULL)

         {

              cerr<<"存储分配错误!"<<endl;

              exit(1);

         }

         newNode->link = first->link;

         first->link = newNode;

         cin>>val;

     }

}

 

//后插法输入建立单链表

template<class T>

void List<T>::InputRear(T endTag)

{

     LinkNode<T> *newNode,*last;

     T val;

     MakeEmpty();

     cin>>val;

     last = first;

     while (val != endTag)

     {

         newNode = new LinkNode<T>(val);

         if (newNode == NULL)

         {

              cerr<<"存储分配错误!"<<endl;

              exit(1);

         }

         last->link = newNode;

         last = newNode;

         cin>>val;

     }

     last->link = NULL;

}

 

//基本线性表的就地逆置

template <class T>

void List<T>::reverse()

{

     LinkNode<T> *p = first->link,*current;

     first->link = NULL;

     while(p != NULL)

     {

         current = p;

         p = p->link;

         current->link = first->link;

         first->link = current;

     }

}

 

//根据链表结点地址计算位置

template <class T>

int List<T>::GetNumber(LinkNode<T> *address)

{

     if(address == NULL)

         return -1;

     else

     {

         LinkNode<T> *current = first;

         int k=0;

         while (current != address)

         {

              ++k;

              current = current->link;

         }

         return k;

     }

}

 

#endif

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值