| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 5557 人关注过本帖
标题:链表排序问题
只看楼主 加入收藏
广陵绝唱
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:29
帖 子:3607
专家分:1709
注 册:2008-2-15
结帖率:94.74%
收藏
 问题点数:0 回复次数:20 
链表排序问题
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    最近一直断断续续地在学习着链表,链表的插入数据一般都要用到排序。在网上搜了几个链表排序的代码,不甚明了,也未能释疑。哪位仁兄能略微详细——或者是通俗一些地讲解一下?最好能帖上个链表排序的函数代码上来,不胜感激。谢谢。
搜索更多相关主题的帖子: 链表 函数 仁兄 代码 数据 
2008-08-16 16:48
爱喝牛奶的猫咪
Rank: 1
来 自:QQ群46520219
等 级:禁止访问
帖 子:513
专家分:0
注 册:2008-6-16
收藏
得分:0 
那要看是什么链表了


[color=white]<" border="0" />>
2008-08-16 16:59
广陵绝唱
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:29
帖 子:3607
专家分:1709
注 册:2008-2-15
收藏
得分:0 
别的没学过,也没学到,是单链表,就是最初级的。

如:
struct ST
{
        char c;
        struct ST *next;
}*p,*pr,*head;

[[it] 本帖最后由 广陵绝唱 于 2008-8-16 19:57 编辑 [/it]]
2008-08-16 19:56
爱喝牛奶的猫咪
Rank: 1
来 自:QQ群46520219
等 级:禁止访问
帖 子:513
专家分:0
注 册:2008-6-16
收藏
得分:0 
单链的话要排序和数组并没有多大区别,但可选算法少很多,天生的排序困难
除非是双链


[color=white]<" border="0" />>
2008-08-16 20:00
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
我有个双向链表的代码,要不?自己写的

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-08-16 20:01
广陵绝唱
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:29
帖 子:3607
专家分:1709
注 册:2008-2-15
收藏
得分:0 
我实在是愚钝得很,现在连什么是双链都不清楚。不过这位仁兄如果有空,请把代码发上来,我学习学习,谢谢。

PS:记得链表排序,好象是应该再在链表最后再加一个链,作为临时交换用链,是这样吗?

再PS:忘说谢谢了,谢谢两位。
2008-08-16 20:04
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
广陵绝唱,我记得你着手学编程已经很久了啊,怎么看起来好象进阶非常慢?而且说话没自信。要有自信啊!你未必比别人差,别人说的话未必对,你不知道的别人也未必知道!
以下是双链代码:
CList.h

#ifndef _LIST_H
#define _LIST_H

#include <windows.h>

class CList;
typedef void* (CALLBACK *LPENUMFUNC)(void *param, int index, void *data);
//////////////////////////////////////////////////////////////////////////
//节点的结构
struct node
{
    void *data;
    node *last;
    node *next;
};

//////////////////////////////////////////////////////////////////////////
//链表类
class CList
{
public:
    //////////////////////////////////////////////////////////////////////////
    //初始化链表
    CList()
    {
        m_curNode = NULL;    //为NULL则说明没有节点
        m_curPos = -1;        //为-1也说明没有节点
    }

    //////////////////////////////////////////////////////////////////////////
    //在当前节点的左边插入一个新节点
    void *insertLeft(void *dat)
    {
        node *newNode = new node;
        newNode->data = dat;
        newNode->last = NULL;
        newNode->next = NULL;

        if(!m_curNode)
        {
            m_curNode = newNode;
            m_curPos = 0;
        }
        else
        {
            node *oldNode = m_curNode->last;
            if(oldNode) oldNode->next = newNode;
            newNode->last = oldNode;
            newNode->next = m_curNode;
            m_curNode->last = newNode;
            m_curNode = newNode;
        }
        return m_curNode->data;
    }

    //////////////////////////////////////////////////////////////////////////
    //在当前节点的右边插入一个新节点
    void *insertRight(void *dat)
    {
        node *newNode = new node;
        newNode->data = dat;
        newNode->last = NULL;
        newNode->next = NULL;
        
        if(!m_curNode)
        {
            m_curNode = newNode;
            m_curPos = 0;
        }
        else
        {
            node *nextNode = m_curNode->next;
            if(nextNode) nextNode->last = newNode;
            newNode->last = m_curNode;
            newNode->next = nextNode;
            m_curNode->next = newNode;
            m_curNode = newNode;
            m_curPos ++;
        }
        return m_curNode->data;
    }

    //////////////////////////////////////////////////////////////////////////
    //删除当前节点
    short deleteNode()
    {
        if(!m_curNode)return 0;
        else
        {
            node *last = m_curNode->last;
            node *next = m_curNode->next;
            if(last) last->next = next;
            if(next) next->last = last;
            
            delete m_curNode;
            m_curNode = NULL;
            
            if(last)
            {
                m_curNode = last;
                m_curPos --;
                return 1;
            }
            else if(next)
            {
                m_curNode = next;
                return 2;
            }
            else
            {
                m_curNode = NULL;
                m_curPos = -1;
                return 0;
            }
        }
    }

    //////////////////////////////////////////////////////////////////////////
    //删除所有节点
    int delAllEx()
    {
        int cnt = 0;
        moveFirst();
        node *tmp = m_curNode;

        do
        {
            deleteNode();
            cnt++;
        } while (tmp = moveRight());

        deleteNode();
        m_curPos = -1;
        cnt++;

        return cnt;
    }

    //////////////////////////////////////////////////////////////////////////
    //删除所有节点(最快)
    int delAll()
    {
        int cnt = 0;
        do cnt ++;
        while (deleteNode());
        return cnt;
    }

    //////////////////////////////////////////////////////////////////////////
    //当前节点往左移动
    node *moveLeft()
    {
        if(!m_curNode)
        {
            //m_curPos = -1;
            return NULL;
        }
        else
        {
            node *tmp = m_curNode->last;
            if(tmp)
            {
                m_curNode = tmp;
                m_curPos --;
                return m_curNode;
            }
            else return NULL;
        }
    }

    //////////////////////////////////////////////////////////////////////////
    //当前节点往右移动
    node *moveRight()
    {
        if(!m_curNode)
        {
            //m_curPos = -1;
            return NULL;
        }
        else
        {
            node *tmp = m_curNode->next;
            if(tmp)
            {
                m_curNode = tmp;
                m_curPos ++;
                return m_curNode;
            }
            else return NULL;
        }
    }

    //////////////////////////////////////////////////////////////////////////
    //当前节点移动到最前
    node *moveFirst()
    {
        while(moveLeft())
        {}
        return m_curNode;
    }

    //////////////////////////////////////////////////////////////////////////
    //当前节点移动到最后
    node *moveEnd()
    {
        while(moveRight())
        {}
        return m_curNode;
    }

    //////////////////////////////////////////////////////////////////////////
    //循环移动当前节点,v为正则往右,负则往左,0则不移动
    void loopMove(int v)
    {
        int idx = 0;
        if(v < 0)
        {
            idx = abs(v);
            for(int i = 0; i < idx; i++)
                moveLeft();
        }
        else if(v > 0)
        {
            idx = abs(v);
            for(int i = 0; i < idx; i++)
                moveRight();
        }
    }

    //////////////////////////////////////////////////////////////////////////
    //当前节点移动到idx位置
    void moveTo(int idx)
    {
        int a = idx - m_curPos;
        loopMove(a);
    }

    //////////////////////////////////////////////////////////////////////////
    //获得当前节点
    node *getCurNode()
    {
        return m_curNode;
    }

    //////////////////////////////////////////////////////////////////////////
    //获得当前节点的位置
    int getCurPos()
    {
        return m_curPos;
    }

    //////////////////////////////////////////////////////////////////////////
    //获得当前节点的data指针
    void *getCurData()
    {
        if(!m_curNode) return NULL;
        else return m_curNode->data;
    }

    //////////////////////////////////////////////////////////////////////////
    //设置当前节点的data指针
    bool setCurData(void *data)
    {
        if(!m_curNode) return false;
        m_curNode->data = data;
        return true;
    }
    //////////////////////////////////////////////////////////////////////////
    //重载等于运算符,把另一个链表复制到此链表
    void operator = (CList lst)
    {
        lst.moveFirst();
        do insertRight(lst.getCurData());
        while (lst.moveRight());
        moveFirst();    //置于最前
    }

    //////////////////////////////////////////////////////////////////////////
    //获得链表中总共有多少个节点
    //这个会把curPos改变,但是速度更快
    int getNumEx()
    {
        moveEnd();
        return m_curPos + 1;
    }

    //////////////////////////////////////////////////////////////////////////
    //这个能保持curPos,但是速度较慢
    int getNum()
    {
        int oldCur = m_curPos;
        moveEnd();
        int ret = m_curPos + 1;
        moveTo(oldCur);
        return ret;
    }

    //////////////////////////////////////////////////////////////////////////
    //遍历所有节点的数据
    void* enumDatas(LPENUMFUNC func, void *param)
    {
        node *oldNode = m_curNode;
        int oldPos = m_curPos;

        do
        {
            void *curData = getCurData();
            if(!curData){}// break;
            else
            {
                void *ret;
                if(ret = func(param, m_curPos, curData))
                    return ret;
            }
        } while (moveLeft());

        m_curNode = oldNode;
        m_curPos = oldPos;
        while (moveRight())
        {
            void *curData = getCurData();
            if(!curData){}// break;
            else
            {
                void *ret;
                if(ret = func(param, m_curPos, curData))
                    return ret;
            }
        }
        return NULL;
    }

    //////////////////////////////////////////////////////////////////////////
    //移动数据,用于游戏排序
    void moveData(int dst, int src)
    {
        void *oldData;
        if(src > dst)
        {
            moveTo(src);
            oldData = getCurData();
            deleteNode();
            moveTo(dst);
            insertLeft(oldData);
        }
        else if(src < dst)
        {
            moveTo(src);
            oldData = getCurData();
            moveTo(dst);
            insertRight(oldData);
            moveTo(src);
            deleteNode();
        }
    }

    //////////////////////////////////////////////////////////////////////////
    //交换两个节点的数据
    void changeData(int posA, int posB)
    {
        if(posA == posB) return;
        void *tmpA, *tmpB;
        moveTo(posA);
        tmpA = getCurData();
        moveTo(posB);
        tmpB = getCurData();
        moveTo(posA);
        setCurData(tmpB);
        moveTo(posB);
        setCurData(tmpA);
    }
protected:
    node    *m_curNode;    //当前节点
    int        m_curPos;    //当前节点的位置
};

#endif

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-08-16 20:11
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
这个是去年打算用来做游戏的链表,不过现在存连续的数据已经改用STL了。
主要是不想搞的自己太麻烦,有什么好用的就用,未必需要自己写

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-08-16 20:14
广陵绝唱
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:29
帖 子:3607
专家分:1709
注 册:2008-2-15
收藏
得分:0 
谢谢祭雪朋友。再问个问题(我还没看代码):双链和单链输出的效果是一样的么?

PS:为了生计,每天疲于奔命,虽自学很长时间,但进程缓慢,有时一耽误就是好几天学不成。虽进展缓慢,但由于没有考试等方面的压力,还算是自得其乐。C语言是我业余的爱好,我现在的收入应该比一般的程序员要多,我学它,算是一种乐趣吧。
2008-08-16 20:20
flyue
Rank: 10Rank: 10Rank: 10
来 自:江南西道
等 级:贵宾
威 望:19
帖 子:3465
专家分:1563
注 册:2006-6-20
收藏
得分:0 
单双跟输出没多大关系,不过双链比单链更快是真的。
把双链看成一列火车,它的每截车厢都是一个节点,它们是互相连接在一起的,第一个连到第二个,第二个连到第一个,并且连到第三个,以此类推(互相连接的形式)

PS:哦,那祝贺你

天之道,损有余而补不足.人之道则不然,损不足以奉有余.孰能有余以奉天下,唯有道者.
2008-08-16 20:24
快速回复:链表排序问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.020604 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved