zoukankan      html  css  js  c++  java
  • C++ 数据结构与算法(三)线性表之双向链表

    前面两篇是关于顺序表和单链表的,下面这个是双向链表,具体实现代码如下:

    结点类文件(ListNode.h):

    template<typename T> class DoubleList;
    template<typename T>
    class ListNode
    {
    private:
        ListNode():m_pprior(NULL),m_pnext(NULL)
        {
    
        }
        ListNode(const T item,ListNode<T>* pprior = NULL,ListNode<T>* pnext = NULL)
        {
            m_data = item;
            m_pprior = pprior;
            m_pnext = pnext;
        }
        ~ListNode()
        {
            m_pprior = NULL;
            m_pnext = NULL;
        }
        friend class DoubleList<T>;
    
    private:
        T m_data;//数据项
        ListNode* m_pprior;//直接前驱指针
        ListNode* m_pnext;//直接后继指针
    };

    双向链表类(DoubleList.h):

    #include "ListNode.h"
    
    template<typename T>
    class DoubleList
    {
    public:
        DoubleList()
        {//使head指向它自己
            head = new ListNode<T>();
            head->m_pprior = head;
            head->m_pnext = head;
        }
        ~DoubleList()
        {
            EmptyList();
            delete head;
        }
    public:
        void EmptyList();//清空链表
        int Length() const;//链表长度
        
        ListNode<T>* Find(T item);//查找与item相等的数据项
        bool Insert(const T item,int n =0);//插入item到第n个数据项,即第n+1个开始都往后移
        void Delete(int n);//删除第n个数据结点
        T GetData(int n) const;//获得第n个数据结点
        void Print();//遍历输出链表所有结点数据
    private:
        ListNode<T>* head;
    };
    
    template<typename T>
    void DoubleList<T>::EmptyList()
    {//清空链表
        ListNode<T>* p = head->m_pnext;
        ListNode<T>* pdel;
        while(p!=head)
        {
            pdel = p;
            p = pdel->m_pnext;
            delete pdel;
    
        }
        p->m_pprior = head;
        p->m_pnext = head;
    }
    template<typename T>
    int DoubleList<T>::Length() const
    {//获取链表长度
        int count = 0;
        ListNode<T>* p = head->m_pnext;
        
        while(p!= head)
        {
            count ++;
            p = p->m_pnext;
        }
        return count;
    }
    template<typename T>
    ListNode<T>* DoubleList<T>::Find(T item)
    {//双向查找
        ListNode<T>* pprior = head->m_pprior;
        ListNode<T>* pnext = head->m_pnext;
        while(pprior->m_pnext != pnext && pprior != pnext)
        {
            if(pprior->m_data == item)
                return pprior;
            if(pnext->m_data == item)
                return pnext;
            pprior = pprior->m_pprior;
            pnext = pnext->m_pnext;
        }
        return NULL;//没有找到    
    }
    template<typename T>
    bool DoubleList<T>::Insert(const T item,int n)
    {//插入数据元素
        if(n < 0)
            return false;
        ListNode<T>* pnewnode = new ListNode<T>(item);
        ListNode<T>* p = head;
        
        for(int i =0 ;i< n;i ++)
        {//让p指向要插入结点位置
            p = p->m_pnext;
            if(p == head)
                return false;
        }
        //插入结点
        pnewnode->m_pnext = p->m_pnext;
        pnewnode->m_pprior = p;
        p->m_pnext = pnewnode;
        p->m_pnext->m_pprior = pnewnode;
        return true;
    }
    template<typename T>
    void DoubleList<T>::Delete(int n)
    {
        if(n < 0)
            return;
        ListNode<T>* p = head;
        ListNode<T>* pdel;
        for(int i =0; i< n ;i++)
        {//找到第n个位置
            p = p->m_pnext;
            if(p == head)
            {
                return;
            }
        }
        //删除结点
        pdel = p;
        p->m_pprior->m_pnext = p->m_pnext;
        p->m_pnext->m_pprior = p->m_pprior;
        delete pdel;
    }
    template<typename T>
    T DoubleList<T>::GetData(int n) const
    {
        if(n < 0)
            return NULL;
        ListNode<T>* p = head;
        
        for(int i =0; i< n ;i++)
        {//找到第n个位置
            p = p->m_pnext;
            if(p == head)
            {
                return NULL;
            }
        }
        
        T data = p->m_data;
        return data;
    }
    template<typename T>
    void DoubleList<T>::Print()
    {
        ListNode<T>* p = head->m_pnext;//p指向第一个结点
        cout << "head" ;
        
        while(p != head)
        {
            cout << "-->" << p->m_data  ;
            p = p->m_pnext;
        }
        cout <<"-->over" << endl ;
    }

    测试类(Doublelist.cpp):

    // Doublelist.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "DoubleList.h"
    #include <iostream>
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        DoubleList<int> doublelist;
        for(int i=0;i<10;i++){
            doublelist.Insert(i*3,i);
        }
        int data = doublelist.GetData(3);
        doublelist.Print();
        cout << doublelist.Length() << endl;
        cout << data <<endl;
        doublelist.Insert(88888,5);
        doublelist.Print();
        cin.get();
        return 0;
    }

    测试截图:

  • 相关阅读:
    9.jQuery工具方法
    8.jQuery遍历索引的方法
    7.jQuery中位置坐标图形相关方法
    CentOS安装log.io
    centos7搭建frps内网穿透服务
    docker showdoc安装
    【测试基础】等价类、边界值的概念及划分
    3-14 Pandas绘图
    3-13 索引进阶
    3-12 字符串操作
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/2979874.html
Copyright © 2011-2022 走看看