按升序排序 - 链接列表

时间:2014-12-28 20:23:12

标签: c++ sorting linked-list

我在解决这个功能如何工作以及我需要做什么方面遇到了一些麻烦。我在我的节点类中有int数字作为我的数据类型和node * next。我还有节点指针head,current和temp。我的问题是如何才能将整数列表整理好?升序和降序如何在单个链表中工作?

我的标题文件:

#ifndef SDI_LL                      
#define SDI_LL                      

namespace SDI
{                                                       

    class LinkedList                                                                    
    {
        class Node                                      
        {
        public:
            int number;                                 //data element
            Node* next;                                 //pointer to next, node inside each node
        private:

        };

    private:

        Node *head;
        Node *current;                                  //head, current and temp node pointers
        Node *temp;

    public:
        LinkedList();                                   //constructor to access nodes from above
        ~LinkedList();                                  //destructor

        void insert(int add);                           
        void remove(int remove);                        //functions that access private data nodes above
        void display();
        void reverse();
        void search(int searchNum);
        void sortAscending();
        void sortDecending();
        void saveAll();
        void restoreAll();

    };

}
#endif

到目前为止我的升序功能从头开始并搜索列表:

void LinkedList::sortAscending()
{
    current = head;
    for (current = head; current;)
    {
        temp = current;
        current = current->next;

    }
}

2 个答案:

答案 0 :(得分:2)

通常,您应该使用标准库中提供的容器,这些容器在适用的情况下提供有效的排序方法。

那就是说,如果你想为了学习目的而这样做 - 因为你可能“应该至少一次” - 那么实施起来并不太难。

for (current = head; current;)

这是一个有趣的for循环,我个人更喜欢:

current = head;
while(current)  // or current != nullptr to be more explicit

另请注意,您(当然不必要)将head分配给current两次 - 紧接在for循环之前,以及初始化之前。

一个简单的方案(但效率不高!)可能只是在遍历列表时交换“乱序”元素,直到不需要交换为止:

bool changeMade;
do{
    changeMade = false;
    current = head;
    while( current ){
        temp = current;
        current = current->next;

        if( current && current->data < temp->data ){
            changeMade = true;
            swap( temp->data, current->data );
        }
    }
} while( changeMade );

这假设data字段是节点中唯一的另一个字段 - 因为它实际上不交换节点,只交换数据。 (做前者实际上并不困难 - 但是如果没有看到你的节点类型声明,我就会编造名称并且会使问题混乱。)

答案 1 :(得分:0)

我没有看到current,head和temp的任何声明,但我认为它们是指向节点的指针。你决定使用排序算法吗?排序算法是否需要高效或者是否具有冒泡排序的性能?使用类似于冒泡排序的逻辑,您可以重复将具有最大值的节点移动到列表的末尾。或者为了节省一些时间,您可以从原始列表中删除具有最大值的节点,并将其插入到最终按排序顺序排列的新列表的前面。更高效的算法使用基于合并排序的逻辑。

要删除或交换节点,使用指向指针的指针可以避免对列表的第一个节点(在此示例中由pList指向的节点)进行特殊处理:

NODE * SortList(NODE * pList)
{
NODE * pNew = NULL;                     /* sorted list */
NODE **ppNode;                          /* ptr to ptr to node */
NODE **ppLargest;                       /* ptr to ptr to largest node */
NODE * pLargest;                        /* ptr to largest node */
    while(pList != NULL){               /* while list not empty */
        ppLargest = &pList;             /*  find largest node */
        ppNode = &((*ppLargest)->next);
        while(NULL != *ppNode){
            if((*ppNode)->data > (*ppLargest)->data)
                ppLargest = ppNode;
            ppNode = &((*ppNode)->next);
        }
        pLargest = *ppLargest;          /* move node to new */
        *ppLargest = pLargest->next;
        pLargest->next = pNew;
        pNew = pLargest;
    }    
    return(pNew);
}