双向循环链表

双向循环链表

//
//  双向循环链表
//
//  Created by chenshang on 14-2-6.
//  Copyright (c) 2014年 chenshang. All rights reserved.
//

#ifndef TestList_DoublyList_h
#define TestList_DoublyList_h

#include 
using namespace std;
typedef int T;
//创建一个节点
class ListNode
{
public:
    ListNode():prior(NULL),next(NULL){}//构造方法,初始化,目的为了创建头结点
    ListNode(const T &d) :data(d), prior(NULL),next(NULL){} //构造方法,初始化,创建结点
    T data;
    ListNode* prior;
    ListNode* next;
};
//创建双向循环链表
class DoublyList{
public:
    //初始化双向循环链表,并创建一个头结点
    DoublyList():head(new ListNode())
    {
        head->prior= head;
        head->next = head;
    }
    ~DoublyList()
    {
        MakeEmpty();
        delete head;
    }
public:
    void MakeEmpty();//清除
    int Length(); //链表的长度
    ListNode* FindData(T value);//找到与value值相等的结点
    ListNode* Find(int n);//找到第n个结点
    bool Insert(T item, int n=0);//往第n个结点的后面插入一个结点,如果要插入第一个结点,就应该在第零个之后
    T Remove(int n=0); //删除第n个结点,这是与单项循环链表是有区别的。
    T Get(int n);//得到第n个结点的数据
    void Print(); //打印链表
    
private:
    ListNode *head;
};
void DoublyList::MakeEmpty(){
    ListNode *pdel,*pmove =head;
    //算法解释:pmove不动,移动pdel
    while (pmove->next!=head) {
        pdel=pmove->next;
        pmove->next=pdel->next;
        delete pdel;
        //注意这句话非常的重要,为什么要加入这句话?
        //使用这种方法在删除双向循环链表的时候,已经破坏了顺序,此时要恢复顺序,以便在Length函数时不出错!
        head->prior = head;
    }
}
//由于是双向循环链表,我们采用前后指针同时移动的方法,从而提高效率。
int DoublyList::Length(){
    ListNode* pprior=head->prior, *pnext =head->next;
    int count =0;
    while (1) {
        //如果两个指针走过了,就要终止循环
        if (pprior->next==pnext) {
            break;
        }
        //相遇了,再加一次计数
        if (pprior==pnext&&pprior!=head) {
            count++;
            break;
        }
        count+=2;
        pprior=pprior->prior; //前移
        pnext=pnext->next; //后移
    }
    return count;
}
//因为已经知道了 第几个结点,所以我们就不采用双向查找的方法了。效率都是一样的
ListNode* DoublyList::Find(int n){
    if (n<0) {
        cout<<"The n is out of boundary"<next;
        if (pmove==head) {
            cout<<"The n is out of boundary"<prior;
    ListNode* pnext = head->next;
    while (pprior->next!=pnext && pprior!=pnext) {
        if (pprior->data==value) {
            return pprior;
        }
        if (pnext->data==value) {
            return pnext;
        }
        pprior = pprior->prior;
        pnext = pnext ->next;
    }
    cout<<"can not find the element"<next;
        if (pmove==head) {
            cout<<"The n is out of boundary" <next = pmove ->next;
    pmove->next = pnode;
    pnode->prior = pmove;
    pnode->next->prior=pnode;
    
    return true;
}

//删除第n个结点,注意这和单项循环链表是有区别的,单项循环链表获取当前结点指针后,只能删除下一个结点,但是双向链表却不一样。
T DoublyList::Remove(int n){
    if (n<0) {
        cout<<"can not find the element"<next!=head; i++) {
        //n次循环后,指向当前第n个结点的指针
        pmove=pmove->next;
    }
    if (pmove->next==head) {
        cout<<"can not find the element"<prior->next = pdel->next;
    pmove->next->prior = pdel->prior;
    T temp =pdel->data;
    delete pdel;
    return temp;
}
//已经知道结点位置,不需要双向循环,只需要单项查询即可!
T DoublyList::Get(int n){
    if (n<0) {
        cout<<"The n is out of boundary"<next;
        if (pmove==head) {
            cout<<"The n is out of boundary"<data;
}
//打印函数
void DoublyList::Print(){
    ListNode* pmove=head->next;
	cout<<"head";
	while(pmove!=head){
		cout<<"--->"<data;
		pmove=pmove->next;
	}
	cout<<"--->over"<


你可能感兴趣的:(数据结构C++代码模板)