首页 > 技术文章 > 数据结构之线性表---C++实现

ITxiansheng 2014-04-17 20:44 原文

线性表的逻辑结构

对于非空的线性表:

(1)有且仅有一个开始结点a1,没有直接前驱,有唯一后继a2;

(2)有且仅有一个终端结点an,没有直接后继,有唯一的直接前驱an-1;

(3)其余的内部结点ai,都有唯一的直接前驱ai-1和直接后继ai+1;

下面给出不同的实际实现:

一、顺序表数据结构

  1 /////////////////////////////////////////////////////
  2 
  3 //SqList.h顺序表数据结构c++定义(基类)
  4 
  5 //////////////////////////////////////////////////
  6 
  7 #ifndef SQLIST_H
  8 #define SQLIST_H
  9 
 10 //顺序表使用的一些常量说明
 11 #define  LIST_MAX_SIZE 100 //顺序表初始存储空间的大小
 12 #define  LISTINCREMENT 10  //顺序表的存储空间增量
 13 #define  ERROR -1;
 14 #define  OK 0;
 15 typedef int Status;
 16 ///////////////////////////////////////////////////
 17 //顺序表数据结构声明(基类)
 18 #include <assert.h>
 19 #include <iostream>
 20 using namespace std;
 21 template <typename ElemType>
 22 class SqList
 23 {
 24 public:
 25     //有序顺序表折半查找
 26     int bin_search(ElemType key);
 27     //把顺序表置空
 28     void clear();
 29     //删除第i个元素
 30     Status deleteElem(int i,ElemType& e);
 31     //取第i个元素
 32     ElemType getElem(int i ,ElemType& e);
 33      //求顺序表中元素的个数
 34      int getLength();
 35      //取顺序表存储空间的大小
 36      int getListSize();
 37      //在第i个元素之前插入一个元素
 38      Status insert(int i,ElemType e);
 39      //判断顺序表是否为空
 40      bool isEmpty();
 41      //查找第1个与e满足compare()关系的元素序号
 42      int locateElem(ElemType e,Status (*compare)(ElemType,ElemType));
 43      //重载赋值运算符的定义
 44      SqList<ElemType> operator = (SqList<ElemType> rightL);
 45      //返回某元素的前驱
 46      Status priorElem(ElemType e, ElemType& prior_e);
 47      //返回某元素的后继
 48      Status nextElem(ElemType e, ElemType& next_e);
 49      //在顺序表中查找某元素
 50      int sequentialSearch(ElemType e);
 51      //********************下面是系统自动调用的构造函数以及析构函数************************
 52 
 53      //顺序表构造函数
 54      SqList();
 55      //顺序表析构函数
 56      ~SqList();
 57      //顺序表靠被初始化构造函数
 58      SqList(const SqList<ElemType>& otherL);
 59 protected:
 60 
 61     ElemType * elem;//顺序表动态存储空间的首地址
 62     int listSize;//顺序表当前已分配的存储空间大小
 63     int n;//顺序表当前元素的个数
 64 private:
 65 };
 66 //////顺序表数据结构C++实现(基类)
 67 
 68 
 69 //功能:在循序表折半查找
 70 //要求:顺序表实现排好序
 71 //输入:指定值key
 72 //输出:如果存在查找元素,则返回该元素的序号(元素的序号从1开始),否则,返回0
 73 template<typename ElemType>
 74 int SqList<ElemType>::bin_search(ElemType key)
 75 {
 76     int low;
 77     int mid;
 78     int high;
 79 
 80     //首先,把顺序表的整个区间设置为初始查找区域
 81     low = 0,high=n-1;
 82     while(low<=high)
 83     {
 84         mid = (low+high)/2;
 85 
 86         if (elem[mid]==key)
 87         {
 88             return mid+1; //返回元素实际的序号
 89         }
 90 
 91         else if (elem[mid]<key)
 92         {
 93             low = mid +1;
 94         }
 95 
 96         else 
 97         {
 98             high = mid -1;
 99         }
100         
101     }
102 
103     return 0;
104 }
105 
106 
107 //功能:把顺序表置空
108 //说明:只是把顺序表当前元素的个数设置为0,并不回收其存储空间
109 
110 template<typename ElemType>
111 void SqList<ElemType> ::clear()
112 {
113     n=0;
114 }
115 
116 //功能:删除第i个元素
117 
118 template <typename ElemType>
119 Status SqList<ElemType>::deleteElem(int i ,ElemType& e)
120 {
121     //判断第i个元素的序号i是否越界
122     if (i<1||i>n)
123     {
124         return false;
125     }
126 
127     e= elem[i-1];
128     //第i个结点以后的数据都向前移动一个位置
129     for (int j =i+1;j<=n;++j)
130     {
131         elem[j-2] = elem[j-1];
132     }
133     --n;//元素个数减1
134     return true;
135 }
136 
137 
138 //功能:取第i个元素
139 
140 template <typename ElemType>
141 ElemType SqList<ElemType>::getElem(int i ,ElemType& e)
142 {
143     //判断i是否越界
144     if (i<1||i>n)
145     {
146         return ERROR;
147     }
148 
149     e=elem[i-1];
150     return e;
151 }
152 
153 
154 
155 //求顺序表中元素的个数
156 
157 template <typename ElemType>
158 int SqList<ElemType>::getLength()
159 {
160     return n;
161 }
162 
163 
164 //功能:去顺序表存储空间的大小
165 
166 template<typename ElemType>
167 int SqList<ElemType>::getListSize()
168 {
169     return listSize;
170 }
171 
172 
173 //功能:在第i个元素之前插入一个元素
174 
175 
176 template <typename ElemType>
177 Status SqList<ElemType>::insert(int i,ElemType e)
178 {
179     ElemType *newbase;
180 
181     if (i<1||i>(n+1))
182     {
183         return ERROR;
184     }
185 //如果现在顺序表中的元素个数大于等于表的容量
186 if (n>=listSize)
187 {//重新申请新的顺序表空间,扩充容量
188     newbase = new ElemType(listSize+LISTINCREMENT);
189     assert(newbase != 0);
190 //将原来顺序表中的元素复制到新的顺序表中
191     for (int j = 1;j<=n;++j)
192     {
193         newbase[j-1] = elem[j-1];
194     }
195     //删除原来顺序表中的元素
196     delete [] elem;
197     //将顺序表的基地址更改为新申请的空间地址
198     elem = newbase;
199     //更新表容量
200     listSize+=LISTINCREMENT;
201 }
202 //从顺序表的最后一个元素开始,直到第i个元素,每个元素后移一位
203 for (int j=n; j>=i;--j)
204 {
205     elem[j] = elem[j-1];
206     
207 }
208 
209     elem[i-1]=e;
210     ++n;
211     return OK;
212 }
213 
214 
215 //功能:判断顺序表是否为空
216 
217 template <typename ElemType>
218 bool SqList<ElemType>::isEmpty()
219 {
220     return n?false:true;
221 }
222 
223 //功能:查找第1个与e满足compare()关系的元素
224 
225 template<typename ElemType>
226 int SqList<ElemType>::locateElem(ElemType e,Status (*compare)(ElemType,ElemType))
227 {
228     //查找满足条件的元素,即从顺序表第一个严肃开始,逐一判断顺序表的当前元素
229     //是否与待查值满足比较关系,直到满足或顺序表查找完毕。
230 
231     for (int i = 1;i<n && !(*compare)(elem[i-1],e);i++);
232     
233     if (i <= n)
234     {
235         return i;
236     }
237     else
238         return 0;
239 }
240 
241 //功能:返回某元素的后继
242 template <typename ElemType>
243 int SqList<ElemType>::nextElem(ElemType e, ElemType& next_e)
244 {
245     int i =locateElem(e,equal);
246     
247     if (i<0||i==n)
248     {
249         return ERROR;
250     }
251     else
252         getElem(i+1,next_e);
253     return OK;
254 }
255 //功能:重载赋值运算符的定义
256 template<typename ElemType>
257 SqList<ElemType> SqList<ElemType>::operator =(SqList<ElemType> rightL)
258 {
259     if (this != &rightL)
260     {
261         delete[] elem;
262         elem = new ElemType(rightL.listSize);
263         assert(elem ! = 0);
264         listSize = rightL.listSize;
265     }
266     n = rightL.n;
267     for (int i =1;i<=n;++i)
268     {
269         elem[i-1]=rightL.elem[i-1];
270     }
271     return *this;
272 }
273 //功能:返回某元素的前驱
274 
275 template<typename ElemType>
276 Status SqList<ElemType>::priorElem(ElemType e, ElemType& prior_e)
277 {
278     int i = locateElem(e,equal);
279     if (i<1)
280     {
281         return ERROR;
282     }
283     else
284         getElem(i-1,prior_e);
285     return OK;
286 }
287 //功能:在顺序表中顺序查找某元素
288 template<typename ElemType>
289 int SqList<ElemType>::sequentialSearch(ElemType key)
290 {
291     for (int i =1;i<=n&&key!=elem[i-1];++i);
292 
293     if (i<=n)
294     {
295         return i;
296     }
297     else
298         return 0;
299 }
300 //**********下面为系统自动调用的构造函数和析构函数的实现*********
301 
302 //功能:初始申请一个LIST_MAX_SIZED大小的动态存储空间,并把当前元素的个数置为0;
303 template<typename ElemType>
304 SqList<ElemType>::SqList()
305 {
306     elem = new ElemType(LIST_MAX_SIZE);
307     assert(elem != 0);
308     listSize = LIST_MAX_SIZE;
309     n= 0;
310 }
311 //功能:顺序表析构函数
312 template <typename ElemType>
313 SqList<ElemType>::~SqList()
314 {
315     //释放顺序表的元素空间
316     delete [] elem;
317 }
318 //功能:顺序表拷贝初始化的顺序表
319 template<typename ElemType>
320 SqList<ElemType>::SqList(const SqList<ElemType>& otherL)
321 {
322     elem = new ElemType(otherL.listSize);
323     assert(elem ! = 0;)
324     listSize = otherL.listSize;
325     n = otherL.n;
326     for (int i =1;i<=n;++i)
327     {
328         elem[i-1] = otherL.elem[i-1]
329     }
330 }
331 #endif
View Code

二、非循环单链表结构

为表示逻辑上的顺序关系,线性链表中的每个数据元素除存储本身的数据元素之外,还存储其后继结点的地址信息即指针next,这两部分信息组成的数据元素的存储映像即结点。

#ifndef LINKLIST_H
#define LINKLIST_H
#include <assert.h>
typedef int Status;
template<typename ElemType>
class LinkList
{
    //非循环单链表结点的C++声明
    class LinkNode
    {
    public:
        ElemType data;
        LinkNode* next;
    };
    //指向结点的指针类型声明
    typedef LinkNode * NodePointer;
    //非循环单链表的逆置
    void adverse();
    //把非循环单链表置空
    void clear();
    //删除非循环单链表中数据为e的第一个结点
    Status deleteElem(ElemType e);
    //删除非循环单链表中的重复值
    void deleteRepeat();
    //取非循环单链表的第i个结点
    Status getElem(int i ,ElemType& e);
    //取第一个结点的指针
    NodePointer getHead();
    //求非循环单链表结点个个数
    int getLength();
    //在第i个结点之前插入数据域为e的结点
    Status insert (int i ,ElemType e);
    //判断非循环单链表是否为空
    bool isEmpty();
    //查找第一个与e满足compare()关系的结点
    Status locateELem(ElemType e,Status (*compare)(ElemType ,ElemType),int& i);
    //返回某结点前驱的数据域
    Status priorElem(ElemType e,ElemType& prior_e);
    //返回某结点后继的数据域
    Status nextElem (ElemType e, ElemType& next_e);
    //重载赋值运算符的定义
    LinkList <ElemType> operator = (LinkList<ElemType> rightL);
////////////////////下面为系统自动调用的构造函数以及析构函数声明////////////
    //非循环单链表的构造函数
    LinkList();
    //非循环单链表的析构函数
    ~LinkList();
    //非循环单链表的靠被初始化构造函数
    LinkList(const LinkList<ElemType>& otherL);
protected:
    //非循环单链表的头指针
    NodePointer head;
};

//////////////////////非循环单链表的C++实现//////////////////////////////////////////

//功能:非循环单链表的逆置

template <typename ElemType>
void LinkList<ElemType>::adverse()
{
    NodePointer r =NULL;
    NodePointer p = NULL;
    NodePointer q =NULL;

    p = head;
    q = p->next;

    while (p)
    {
        p->next = r;
         r = p;
         p =q;
        if (q)
        {
            q = q->next;
        }
    }
    head = r;

}
//功能:把非循环单链表置空
template<typename ElemType>
void LinkList<ElemType> ::clear()
{
    NodePointer p = NULL;//指向欲删除的结点
    NodePointer q = NULL;//指向欲删除结点的后继
    q= head;
    while(q)
    {
         p =q;
         q = q->next;
         delete p;
    }
    head = NULL;
}
//功能: 删除非循环单链表中数据域为e的第一个结点
template<typename ElemType>
Status LinkList<ElemType>::deleteElem(ElemType e)
{
    NodePointer r =NULL;//指向欲删除结点的前驱
    NodePointer p = NULL;//指向欲删除的结点
    p = head;
    while(p && !equal(p->data,e))
    {
        r = p;
        p = p->next;
    }
    //如果找到链表表尾,则返回-1
    if ( p == NULL)
    {
        return -1;
    }
    //否则删除该结点,重新链接链表
    else
        r->next = p->next;
    delete p;

     return 0;
}

//功能:删除非循环单链表中的重复值
//步骤:(1)查找指针p所指的当前结点是否与前面的每个结点有重复值,即从非循环单链表的第一个结点(s指向)开始,
//直到指针p所指的当前结点为止,逐一判断指针s所指结点的数据域是否与指针p所指的当前结点相同;如果相同转向(2);
//否则r和p均向前移动一个位置,重复(1);
//(2)将删除s所指结点,r和p均向前移动一个为位置。
template<typename ElemType>
void LinkList<ElemType>::deleteRepeat()
{
    NodePointer r =NULL;//指向前驱结点的指针
    NodePointer p = NULL;//指向欲比较结点的指针
    NodePointer s = NULL;

    p = head;

    while(p)
    {
        s = head;
        while(s!=p)
        {
            if (s->data == p->data)
            {
                r->next = p->next;
                delete p ;
                p = r;
                break;
            }
            s= s->next;
        }
        r = p;
        if (p)//判断p是否到达链表尾部
        p = p->next;

    }
}
//功能:取非循环单链表的第i个结点

template <typename ElemType>
Status LinkList<ElemType>::getElem(int i ,ElemType& e)
{
    
    NodePointer p = head;
    int j = 1;

    while(p && j<i)
    {
        p = p->next;
        ++j;
    }

    if (!p || j>i)
    {
        return ERROR;
    }

    e = p->data;
    return OK;
    
}

//功能:取非循环单链表的头指针head
template<typename ElemType>
typename LinkList<ElemType>::NodePointer LinkList<ElemType>::getHead()
{
    return head;
}
//功能:求非循环单链表结点的个数
template <typename ElemType>
int LinkList<ElemType>::getLength()
{
    int n = 0;//记录此时结点的个数

    NodePointer p = head;

    while(p)
    {
        ++n;
        p = p->next;
    }
    return n;
}

//功能:在第i个结点之前插入一个数组域为e的结点
template<typename ElemType>
Status LinkList<ElemType>::insert(int i ,ElemType e)
{
    int j =1;
    NodePointer p =head;//用来指向所插位置的前驱
    NodePointer s;//指向新申请结点的地址
    //指针p向前移动到第i-1个结点的位置
    while(p && j<i-1)
    {
        ++j;
        p = p->next;
    }

    if (!p ||j>i)
    {
        return ERROR;
    }

     s = new LinkNode;
     assert(s ! = 0);

     s->data = e;
     //如果在第一个位置插入
     if (i=1)
     {
         s->next = head;
         head =s;
     }
     else 
     {
         s->next = p->next;
         p->next = s;
     }
     return OK;
}
//功能:判断非循环单链表是否为空
template<typename ElemType>
bool LinkList<ElemType>::isEmpty()
{
    return(head?false:true);
}

//功能:查找第一个数据域与e满足compare()比较关系的点
template <typename ElemType>
Status LinkList<ElemType>::locateELem(ElemType e,Status (*compare)(ElemType ,ElemType),int& i)
{
    
    NodePointer  p =head;
    i =1;
    //从第一个结点开始,查找与e满足compare关系的结点
    while( p && !(*compare)(p->data,e))
    {
         p = p->next;
         ++i;
    }
    //如果p为空,则返回错误
    if (!p)
    {
        return ERROR;
    }

    return OK;

}

//功能:返回某结点(数据域为e)后继的数据域
template <typename ElemType>
Status LinkList<ElemType>::nextElem(ElemType e, ElemType& next_e)
{
    NodePointer p =head;

    while (p && !equal(p->data,e))
    {
        p = p->next;
    }

    if (!p||!p->next)
    {
        return ERROR;
    }

    next_e = p->next->data;
    return OK;
}

//功能:重载赋值运算符的定义

template <typename ElemType>
LinkList<ElemType> LinkList<ElemType>::operator =(LinkList<ElemType>rightL)
{
    NodePointer p =NULL;//指向新链表的最后一个元素的指针
    NodePointer rp =rightL.getHead();//rp为欲赋值链表的头指针
    NodePointer s = NULL;//指向新申请结点的指针

    if (this != &rightL)
    {
        clear();

        while (rp)
        {
            s =new LinkNode;
            assert(s!=0);
            s->data = rp->data;

            if (!head)
            {//如果头指针为空,则将头指针指向新结点
                head =s ;
            }
            else
                p->next = s;
            p =s;//将p指向新申请的结点
            rp = rp->next;//指针前移
        }
        if (p)
        {
            p->next = NULL
        }
    }
    return *this;


}


//功能:返回某结点(数据域为e)前驱的数据域

template <typename ElemType>
Status LinkList<ElemType>::priorElem(ElemType e,ElemType& prior_e)
{
    NodePointer r =NULL;//指向欲查找结点的前驱
    NodePointer p = head;//指向欲查找的结点


    while (p && !equal((p->data,e)))
    {
        r = p ;
        p = p->next;
    }

    if (!p || !r)
    {
        return ERROR;
    
    }
    prior_e = r->data;
    return OK;
}

//*************下面为系统自动调用的构造函数以及析构函数的实现****************************

//功能:非循环单链表构造函数
template <typename ElemType>
LinkList <ElemType>::LinkList()
{
    head = NULL;
}
//非循环单链表析构函数
template<typename ElemType>
LinkList<ElemType>::~LinkList()
{
    clear();
}

//功能:非循环单链表拷贝初始换构造函数
//类似赋值操作符
template <typename ElemType>
LinkList<ElemType>::LinkList(const LinkList& otherL)
{
     NodePointer p = NULL;//预指向当前非循环单链表当前结点的指针
     NodePointer op = otherL.head;
     NodePointer s = NULL;//预指向新结点的指针
     head =NULL;
     while(op)
     {
         s = new LinkNode;
         assert(s != 0);
         s->data = op->data;
         if (!head)
         {
             head = s;
         }
         else
             p->next = s;

         p=s;
         op=op->next;
     }
     if (head)
     {
         p->next = NULL;
     }
}
#endif
View Code

三、循环单链表结构

和非循环单链表的操纵基本一致,差别仅在于当前指针沿着链表滑动时,如何判断到达链表的结尾,其条件是否为空,该为是否与头指针相同。而且最后一个结点的指针域next设置为指向头结点。

///////////////////////////////////////////////////////////////////////
//////////////////循环单链表数据结构C++声明(基类)//////////////////
///////////////////////////////////////////////////////////////////////
typedef int Status ;
template <typename ElemType>
class CircularLinkList
{
public:
    class LinkNode
    {
    public:
        ElemType data;
        LinkNode * next;
    };
    typedef LinkNode * NodePointer;

    //把循环单链表置空
    void clear();

    //删除第i个结点,头指针移至下一个结点

    Status deleteElem(int i ,ElemType& e);

    //取循环单链表第一个结点的数据域

    Status getHeadElem(ElemType& e);

    //判断循环单链表是否为空
    
    bool isEmpty();

    //把循环单链表的头指针后移至第i个结点

    Status moveHead(int i);

    //重载赋值运算符

    CircularLinkList<ElemType> operator= (CircularLinkList<ElemType>& rightL);

    //********************下面为系统自用调用的构造函数以及析构函数声明********

    //循环单链表构造函数

    CircularLinkList();

    //循环单链表析构函数

    virtual ~CircularLinkList();

    //循环单链表拷贝初始化函数

    CircularLinkList(const CircularLinkList& otherL);
protected:
    NodePointer  head;
};





/////////////////////////////////////////////////
///循环单链表的C++实现
/////////////////////////////////////////////////

//功能:把循环单链表置空

template<typename ElemType>
void CircularLinkList<ElemType>::clear()
{
    NodePointer p;
    while(head !=head->next)
    {
        p=head->next;
        head->next = p->next;
        delete p;
    }
    delete head;
    head = NULL;
}
//功能:删除第i个结点,头指针移至其下一个结点
template<typename ElemType>
Status CircularLinkList<ElemType>::deleteElem(int i ,ElemType& e)
{
    int j =1;
    NodePointer r =NULL;
    NodePointer p =head;

    if (!head)
    {
        return ERROR;
    }

    while(j<i)
    {
        r = p;
        p=p->next;
        ++j;
    }

    e=p->data;
    //如果链表只有一个结点,则将head置空
    if (p == p->next)
    {
        head=NULL;
    }
    else
    {
        r->next = p->next;
        head = r->next;
    }
         delete p;
         return OK;
}


//功能:取循环单链表第一个结点的数据域

template<typename ElemType>
Status CircularLinkList<ElemType>::getHeadElem(ElemType& e)
{
    if (!head)
    {
        return ERROR;
    }
    e=head->data;
    return OK;
}
//功能:判断循环单链表是否为空
template<typename ElemType>
bool CircularLinkList<ElemType>::isEmpty()
{
    return (head?false:true);
}
//功能:把循环单链表的头指针移到第i个结点
template<typename ElemType>
Status CircularLinkList<ElemType>::moveHead(int i)
{
    int j= 1;
    NodePointer priorHead = head;
    //如果链表为空,返回错误
    if (!head)
    {
        return ERROR;
    }
    while(j<i)
    {
        head = head->next;
        ++j;
        //如果结点总数小于i,则返回错误
        if (head =priorHead)
        {
            return ERROR;
        }
    }
    return OK;
}
//功能:重载赋值运算符的定义
template<typename ElemType>
CircularLinkList<ElemType> CircularLinkList<ElemType>::operator =(CircularLinkList& rightL)
{
    NodePointer p =NULL;
    NodePointer rp = rightL.head;
    NodePointer s;
    if ( this!=&rightL )
    {
        clear();

    while (rp->next != rightL.head)
    {
        s =new LinkNode;
        assert(s!=0);

        s->data = rp->data;

        if (!head)
        {
            head =s;
        }
        else
        {
            p->next = s;
        }
        p= s;
        rp = rp->next;
    }
   if(head)
   {
       p->next = head;//最后一个结点的后继为头结点
   }
    }
    return *this;
} 



////////////////下面是系统自动调用的构造函数和析构函数//////////////
//功能:循环单链表构造函数

template <typename ElemType>
CircularLinkList <ElemType>::CircularLinkList()
{
    head = NULL;
}

//功能:循环单链表析构函数

template<typename ElemType>
CircularLinkList<ElemType>::~CircularLinkList()
{
    clear();
}
//功能:循环单链表拷贝初始化构造函数
template<typename ElemType>
CircularLinkList<ElemType>::CircularLinkList(const CircularLinkList& otherL)
{
    NodePointer p = NULL;

    NodePointer op = otherL.head;

    NodePointer s = NULL;

     head = NULL;
     

     while(op != otherL.head)
     {
         s =new(LinkNode);
         assert(s != 0);

         s->data = op->data;

         if (!head)
         {
             head = s;
         }
         else
             p->next = s;
         p=s;
         op = op->next;
     }
     if (head)
     {
         p->next = head;
     }
}
View Code

四、循环双链表结构

在循环单链表中,给每个结点增加一个指针域prior,用于指向其前驱结点,第一个结点的前驱指针prior指向最后一个结点,即为循环双链表。

#ifndef DOUBLELINKLIST_H
#define  DOUBLELINKLIST_H
typedef int Status;
#include <iostream>
using namespace std;

template <typename ElemType>
class DoubleLinkList
{
public:
    class LinkNode
    {
    public:
        ElemType data;
        LinkNode *next;
        LinkNode *prior;
    };
    //定义结点指针
    typedef LinkNode* NodePointer;
    //把循环双链表置空
    void clear();

    //删除循环双链表中数据域为e的第一个结点

    Status deleteElem(ElemType e);


    //取循环双链表的头指针
    NodePointer getHead();

    //求双循环链表中的结点个数

    Status getLength();

    //在第i个结点之前插入一个数据域为e的结点
    Status insert(int i ,ElemType e);

    //判断循环双链表是否为空

    bool isEmpty();

    //返回双循环链表中数据域为e的第i个结点的指针
    Status locataElem(ElemType find_e,NodePointer &r);
    //去双环双链表中第i个结点
   
    Status getElem(int i ,ElemType& e);

    //返回某结点的后继的数据域

    Status nextElem(ElemType e ,ElemType& next_e);

  //重载赋值运算符的定义

    DoubleLinkList<ElemType> operator = (DoubleLinkList<ElemType>& rightL);

    //返回某结点前驱的数据域

    Status priorElem(ElemType e,ElemType& prior_e);

///********************************下面是双循环链表的构造函数和析构函数 拷贝构造函数的声明*********

    //双循环链表的构造函数

    DoubleLinkList();

    //双循环链表的析构函数

    ~DoubleLinkList();

    //双循环链表的拷贝初始化构造函数

    DoubleLinkList(const DoubleLinkList &otherL);
    
protected:
    NodePointer head;
};
///******以下是双循环链表的C++数据结构实现**********

//功能:将双循环链表置空
template<typename ElemType>
void DoubleLinkList<ElemType>::clear()
{
    NodePointer r = NULL;//指向欲删除结点的前驱
    NodePointer p = NULL;//指向欲删除的结点
    //如果链表为空,返回
    if (!head)
    {
        return;
    }
    //如果链表不为空,从头结点的prior开始,即最后一个结点开始回收结点,然后向前逐一回收结点。
    p = head->prior;
    while(p!=head)
    {
        r = p->prior;
        delete p;
        p=r;
    }
    delete p ;
    head = NULL;
}
//功能:删除双循环链表中数据域为e的第一个结点
template<typename ElemType>
Status DoubleLinkList<ElemType>::deleteElem(ElemType e)
{
    NodePointer p =head;
    //如果不存在数据为e的结点,返回错误
    if (!locataElem(e,p))
    {
        return ERROR;
    }
    else
    {
        if (p == head)
        {
            head = p->next;
        }
        //断掉p
        p->prior->next = p->next;
        p->next->prior = p->prior;
    }
    delete p ;
    return OK;
}



//功能:取循环双链表第i个结点的数据域

template<typename ElemType>
Status DoubleLinkList<ElemType>::getElem(int i ,ElemType& e)
{
    int j =1;

    NodePointer p =head;
    while(p && p->next != head && j<i)
    {
        p = p->next;
        ++j;
    }
    if (j == i)
    {
        e = p->data;
        return OK;
    }
    return ERROR;

}
//功能:取循环双链表的头指针
template<typename ElemType>
typename DoubleLinkList<ElemType>::NodePointer DoubleLinkList<ElemType>::getHead()
{
    return head;
}
//功能:求循环双链表中结点的个数
template<typename ElemType>
int DoubleLinkList<ElemType>::getLength()
{
    NodePointer p =head;
    int length = 0;
    while (p)
    {
        ++length;
        p = p->next;
        if (p==head)
        {
            break;
        }
    }
    return length;
}
//在第i个结点之前插入一个数据域为e的结点
template <typename ElemType>
Status DoubleLinkList<ElemType>::insert(int i,ElemType e)
{
    int j =1;
    NodePointer p = head;
    NodePointer s =NULL;

    while(p && p->next!= head && j<i)
    {
        p = p->next;
        ++j;
    }
    if (!head && i!=1 || j<i)
    {
        return ERROR;
    }

    s = new(LinkNode);
    assert(s != NULL);

    s->data = e;

    if (i = =1)
    {
        if (!head)
        {
            head = s->prior = s->next =s;
            return OK;
        }
        head = s;
    }
    p->prior->next = s;
    s->prior = p->prior;
    p->prior = s;
    s->next = p;
    return OK;
}

//功能:判断双循环链表是否为空
template <typename ElemType>
bool DoubleLinkList<ElemType>::isEmpty()
{
    return (head?false::true);
}
//功能:返回循环双链表中数据域为e的第一个节点的指针
template <typename ElemType>
Status DoubleLinkList<ElemType>::locataElem(ElemType find_e,NodePointer &r)
{
    NodePointer p = head;

    while(p && p->data!=find_e && p->next != head)
    {
        p=p->next;
    }
    if (p->data == find_e)
    {
        r = p;
        return OK;
    }
    else
    {
        return ERROR;
    }
}

//功能:返回某结点后继的数据域
template<typename ElemType>
Status DoubleLinkList<ElemType>::nextElem(ElemType e ,ElemType& next_e)
{
    NodePointer p = NULL;
    if (locataElem(e,p))
    {
        next_e = p->next->data;
        return OK;
    }
    else
    {
        return ERROR;
    }
}
//功能:重载赋值运算符的定义
template<typename ElemType>
DoubleLinkList<ElemType> DoubleLinkList<ElemType>::operator = (DoubleLinkList<ElemType>& rightL)
{
    NodePointer p = NULL;
    NodePointer rp = rightL.head;
    NodePointer s = NULL;

    if (this != &rightL)
    {
        clear();
         
        while(rp->next != rp.head)
        {
            s = new LinkNode;

            assert(s != NULL);

            s->data = rp->data;

            if (!head)
            {
                head = p = s;

            }

            p->next =s;
            s->prior =p;

            p=s;
            rp = rp->next;
        
        }
        //设置头指针指向前驱指向最后一个结点,最后一个结点的后继指向第一个结点
        if (head)
        {
            head->prior = p;
            p->next = head;
        }
    }
    return *this;
}


//功能:返回某结点前驱的数据域
template<typename ElemType>
Status DoubleLinkList<ElemType>::priorElem(ElemType e,ElemType& prior_e)
{
    NodePointer p = NULL;
    if (locataElem(e,p))
    {
        prior_e = p->prior->data;
        return OK;

    }
    else
        return ERROR;
}
//***************************下面为系统自动调用的构造函数、析构函数、拷贝初始化函数*********************

//功能:循环双链表构造函数

template <typename ElemType>
DoubleLinkList<ElemType>::DoubleLinkList()
{
    head =NULL;
}

template<typename ElemType>
DoubleLinkList<ElemType>::~DoubleLinkList()
{
    clear();
}

template<typename ElemType>
DoubleLinkList<ElemType>::DoubleLinkList(const DoubleLinkList& otherL)
{
    NodePointer p = NULL;
    NodePointer op = otherL.head;

    NodePointer s = NULL;

    head = NULL;

    while(op->next != otherL.head)
    {
        s= new LinkNode;
        assert(s != NULL);
        s->data = op->data;

        if (!head)
        {
            head = p =s;
        }

        p->next = s;
        s->prior = p;

        p=s;
         op=op->nxet;
    
    }
    if (head)
    {
        head->prior = p;
        p->next = head; 
    }
}
#endif
View Code

 

推荐阅读