反转C ++中的DoublyLinked列表

年轻的一切

我正在学习C ++并对其进行实验。现在,我到了一个非常不喜欢我的解决方案的地步。

#include <iostream>

using namespace std;

//template<class T>
class List{
    public:
    struct ListElem {
            ListElem(int iElem, ListElem* iNext, ListElem* iPrev): mElem(iElem), pNext(iNext), pPrev(iPrev){
                if(pNext != nullptr){
                    pNext->pPrev = this;
                }
                if(pPrev != nullptr){
                    pPrev->pNext = this;
                }
            }

            friend ostream& operator<<(ostream& os,const ListElem& crArg) {
            os << " " << crArg.mElem;
            if (crArg.pNext)
                os << *crArg.pNext;
            return os;
        }


        public:
            int mElem;
            ListElem* pNext;
            ListElem* pPrev;
    };




    void push_front(int iElem){
        if(mHead == nullptr){
            mTail = mHead = new ListElem(iElem,mHead,nullptr);
        }else{
            mHead = new ListElem(iElem,mHead,nullptr);
        }

    }


    void push_back(int iElem){
        if(mTail == nullptr){
            mHead = mTail = new ListElem(iElem,nullptr,mTail);
        }else{
            mTail = new ListElem(iElem,nullptr,mTail);
        }

    }



    void invert(){
        for(ListElem* elem = mHead; elem != nullptr; elem = elem->pPrev){
            ListElem* tmp = elem;
            tmp = elem->pNext;
            elem->pNext = elem->pPrev;
            elem->pPrev = tmp;
        }
        ListElem* pTmpTail = mTail;
        mTail = mHead;
        mHead = pTmpTail;
    }


        friend ostream& operator<<(ostream& os,const List& crArg) {
        if (crArg.mHead)
            os << *crArg.mHead;
        return os;
    }



    private:
        ListElem* mHead = nullptr;
        ListElem* mTail = nullptr;
};




int main(){
    List l;
    l.push_back(1);
    l.push_front(10);
    l.push_back(40);
    l.push_back(30);
//  l.push_front(10);
//  l.push_front(20);
//  l.push_back(30);
    cout << l << endl;
    l.invert();
    cout << l << endl;
    return 0;
}

这是我的代码,我想反转列表。我的功能可以正常工作, invert()但是很难看,对我来说,不是很好。我找到了一个任务,它说:我只能遍历列表一次,并且不使用任何其他帮助者列表或动态数据结构。此外,它应适用于列表的偶数和奇数元素。

你怎么看?有没有更好的方法来解决这个问题。也许更聪明,更易读?

用户名
void invert(){
    ListElem* lo = mHead;
    ListElem* hi = mTail;

    while (lo != hi && //have not met
           lo->pPrev != hi) // have not crossed
    {
        std::swap(lo->mElem, hi->mElem);
        lo = lo->pNext;
        hi = hi->pPrev;
    }
}

这是做什么的:

  1. lo以及hi列表的开头和结尾
  2. 测试lo并且hi尚未收敛。
    1. 空列表大小写已处理loh并且都指向NULL并等于
    2. 处理了1个案例lohi并且都指向同一个节点并且相等。
  3. lohi的节点上交换数据它不交换节点。对于int,交换数据比更改必须更新的4个链接要容易得多。对于较大的数据,这可能不成立,但是功能的复杂性会上升。您的电话是否值得。
  4. 重新指向lohi使其更趋于融合。
  5. 转到2。

由于列表中的数据交换了收敛的方式,因此迭代的长度永远不会超过2。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章