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;
    }

    测试截图:

  • 相关阅读:
    Redis源码分析(二十一)--- anet网络通信的封装
    leetcode 总结part1
    leetcode String to Integer (atoi)
    leetcode 165. Compare Version Numbers
    leetcode 189. Rotate Array
    leetcode 168. Excel Sheet Column Title
    leetcode 155. Min Stack
    leetcode 228. Summary Ranges
    leetcode 204. Count Primes
    leetcode 6. ZigZag Conversion
  • 原文地址:https://www.cnblogs.com/JczmDeveloper/p/2979874.html
Copyright © 2011-2022 走看看