交换双链表中的节点 - 慢速排序算法会丢弃节点

时间:2010-10-18 13:50:45

标签: c struct linked-list

对于练习,我一直在研究一种压缩器,它可以执行查找重复部分,制作字典,压缩霍夫曼代码的事情。

它并没有真正起作用。

其中一个问题是,由于某些原因,我的排序算法会从字典中删除关键字。我认为问题出在交换例程中,但我不确定。 (这个例程交换相邻的关键字,接下来是current-> next。)

我有一个静态关键字* head;

void swap(keyword * current, keyword * next) {
  keyword * prev = current->prev;
  if (prev){
    prev->next = next;
    next->prev = prev;
  } else { /* no prev - current is head */
    head = next;
    next->prev = 0;
  }
  current->prev = next;
  current->next = next->next;
  next->next = current;
}

发现这有什么问题吗?

2 个答案:

答案 0 :(得分:5)

您未设置next->next->prev

正确地使数据结构实现正确是非常困难的。发现这种事情的方法是找出需要更新的指针数量(6)。你只是更新5,所以必须丢失一个!

答案 1 :(得分:1)

我见过许多与链接列表相关的问题,因此我决定分享我的链接列表版本,以便对其进行调整和/或改进。这个版本是用C ++编写的,为节省空间省略了一些方法:

class Node {    
    friend class LinkedList;
public:
    Node();
    Node(const node& krNode);
    explicit Node(const int kiData);
    virtual ~Node();
    Node& operator=(const Node& krNode);
    int GetData(void) const {return _idata; }
private: int _iData; Node* _pNetxNode; 
}
Node::Node(): _iData(0), _pNextNode(0) {}
Node::Node(const Node& krnode): _iData(krNode._iData), _pNextNode(0) {}
Node::~Node() {}
Node& Node::operator=(const Node& krNode) {_iData = krNode._iData; return *this; }

class LinkedList {
public:
    LinkedList();
    virtual ~LinkedList();
    int GethLenght(void) {return _iSize;}
    void Append(Node* pNode);
    void Insert(const int kiIndex, node* pNode);
    Node* GetItem(const int kiIndex);
    int IndexOf(Node* pNode);
    void Remove(const int kiInde);  
    void Swap(constconst int kiIndexA, const int kiIndexB); 
    void Clear(void);
    void Print(void);
protected:
    LinkedList(const LinkedList& krLinkedList);
    LinkedList& operator=(const LinkedList& krLinkedList);
private:
    Node* Detach(const int kiIndex);
    Node* _pFirstNode;
    Node* _pLastNode;
    int _iSize;
}

LinkedList::LinkedList() : _pFirstNode(0), _pLastNode(0), _iSize(0) {}
LinkedList::~LinkedList() { Clear(); }
void LinkedList::Append(Node* pnode) { if(0==_iSize{_pFistrNode = pNode; } else { _pLastNode->_pNextNode = pnode; } _pLastNode = pNode; _iSize++; }
void LinkedList::Insert(const int kiIndex, node* pNode) {
    Node* pNext = 0; Node* pPrevious = 0;
    if(0==_iSize) { Append(pNode); }
    else {
        if(0==kiIndex){ pNode->_pNextNode = _pFirstNode; _pFirstNode = pNode; }
        else { pPrevious = Getitem(kiIndex-1); pNext=pPrevoius->_pNextnode; pNode->_pNextNode=pNext; pPrevious->_pNextnode=pNode;}
    } _iSize++;
}
Node* LinkedList::GetItem(const int kiIndex){
    Node* pNode = _pFirstNode; int iCounter = 0;
    while(icounter++ != kiIndex) { pNode = pNode->_pNextnode; }
    return pNode;
}

int LinkedList::IndexOf(Node* pSearchNode){
    node* pNode = _pFirstnode; int iIndex=0;
    while(o != pNode) { if(pnode==pSearchNode) { break;} iIdex++; pNode=pnode->_pnextnode; }
    if(iIndex ==_iSize) {iIndex = -1;}
    return iIndex;
}

void LinkedList::Remove(const int kiIndex){ delete Detach(kiIndex); }

void LinkedList::Swap(const int kiIndexA, const int kiIndexB){
    int iLowIndex = 0; int iHighIndex = 0;
    if(kiIndex>==kiIndexB) {return;}
    iLowIndex = (kiIndexA < kiIndexB) ? kiIndexA : kiIndexB;
    iHighIndex = (kiIndexA > kiIndexB) ? kiIndexA : kiIndexB;
    Insert(iHighIndex, Detach(iLowIndex));
    Insert(iLowIndex, Detach(iHighIndex-1));
}
void LinkedList::Clear(void) {
    Node* pNode=_pFirstNode; while(0!=pnode){delete pNode; pNode=pNode-_pNextNode;}
    _pFirstnode=0; _pLastnode=0;
}
void LinkedList::Print(void) {
    Node* pNode = _pFirstNode;
    while(0 != pnode) {printf("%d ", pNode_iData); pNode = pNode->_pNextNode;}
}
Node* LinkedList::Detach(const int kiindex){
    Node* pnode = _pFirstnode; Node* pToDetachNode = 0;
    if(kiIndex==0){
        pToDetachNode = _pFirstNode; _pFirstNode=pnode->_pNextNode; if(1==_iSize){_pLastNode=0;}
    }
    else{
        Node* pPreviousNode = GetItem(kiIndex-1);
        pToDetachNode = pPreviousNode->_pNextNode;
        if(kiIndex<_iSize){pPreviousNode->_pNextNode=pPreviousNode->_pNextnode; }
        else {pPreviousNode->_pNextnode=0; _pLastNode=pPrevoiusNode;}
    }_iSize--;
}