| 编程中国 | 业界新闻 | 技术文章 | 视频教程 | 下载频道 | 程序源码 | 个人空间 | 编程论坛
全能ASP/PHP/ASP.NET主机,支持月付专业 MSSQL 数据库空间,支持月付专业 MySQL 数据库空间,支持月付学习型 ASP/PHP/ASP.NET 主机 30元/年
高端软件开发 = 年薪十万不是梦赛孚耐:软件保护加密专家身份认证令牌USB KEY 
共有 1190 人关注过本帖
标题:链表排序问题
收藏  订阅  推荐  打印 
广陵绝唱
Rank: 4
等级:高级会员
威望:1
帖子:825
积分:9718
注册:2008-2-15
链表排序问题

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    最近一直断断续续地在学习着链表,链表的插入数据一般都要用到排序。在网上搜了几个链表排序的代码,不甚明了,也未能释疑。哪位仁兄能略微详细——或者是通俗一些地讲解一下?最好能帖上个链表排序的函数代码上来,不胜感激。谢谢。
搜索更多相关主题的帖子: 链表  函数  仁兄  代码  数据  
2008-8-16 16:48
爱喝牛奶的猫咪
Rank: 2
来自:QQ群46520219
等级:ID已被封
帖子:514
积分:5824
注册:2008-6-16

那要看是什么链表了


[color=white]<>
2008-8-16 16:59
广陵绝唱
Rank: 4
等级:高级会员
威望:1
帖子:825
积分:9718
注册:2008-2-15

别的没学过,也没学到,是单链表,就是最初级的。

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

[ 本帖最后由 广陵绝唱 于 2008-8-16 19:57 编辑 ]
2008-8-16 19:56
爱喝牛奶的猫咪
Rank: 2
来自:QQ群46520219
等级:ID已被封
帖子:514
积分:5824
注册:2008-6-16

单链的话要排序和数组并没有多大区别,但可选算法少很多,天生的排序困难
除非是双链


[color=white]<>
2008-8-16 20:00
flyue
Rank: 6Rank: 6
等级:金牌会员
威望:6
帖子:1721
积分:17882
注册:2006-6-20

我有个双向链表的代码,要不?自己写的

大家一起来编程吧!
2008-8-16 20:01
广陵绝唱
Rank: 4
等级:高级会员
威望:1
帖子:825
积分:9718
注册:2008-2-15

我实在是愚钝得很,现在连什么是双链都不清楚。不过这位仁兄如果有空,请把代码发上来,我学习学习,谢谢。

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

再PS:忘说谢谢了,谢谢两位。
2008-8-16 20:04
flyue
Rank: 6Rank: 6
等级:金牌会员
威望:6
帖子:1721
积分:17882
注册:2006-6-20

广陵绝唱,我记得你着手学编程已经很久了啊,怎么看起来好象进阶非常慢?而且说话没自信。要有自信啊!你未必比别人差,别人说的话未必对,你不知道的别人也未必知道!
以下是双链代码:
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-8-16 20:11
flyue
Rank: 6Rank: 6
等级:金牌会员
威望:6
帖子:1721
积分:17882
注册:2006-6-20

这个是去年打算用来做游戏的链表,不过现在存连续的数据已经改用STL了。
主要是不想搞的自己太麻烦,有什么好用的就用,未必需要自己写

大家一起来编程吧!
2008-8-16 20:14
广陵绝唱
Rank: 4
等级:高级会员
威望:1
帖子:825
积分:9718
注册:2008-2-15

谢谢祭雪朋友。再问个问题(我还没看代码):双链和单链输出的效果是一样的么?

PS:为了生计,每天疲于奔命,虽自学很长时间,但进程缓慢,有时一耽误就是好几天学不成。虽进展缓慢,但由于没有考试等方面的压力,还算是自得其乐。C语言是我业余的爱好,我现在的收入应该比一般的程序员要多,我学它,算是一种乐趣吧。
2008-8-16 20:20
flyue
Rank: 6Rank: 6
等级:金牌会员
威望:6
帖子:1721
积分:17882
注册:2006-6-20

单双跟输出没多大关系,不过双链比单链更快是真的。
把双链看成一列火车,它的每截车厢都是一个节点,它们是互相连接在一起的,第一个连到第二个,第二个连到第一个,并且连到第三个,以此类推(互相连接的形式)

PS:哦,那祝贺你

大家一起来编程吧!
2008-8-16 20:24
关于我们 | 广告合作 | 编程中国 | 清除Cookies | Archiver | WAP | TOP

编程中国 版权所有,并保留所有权利。鲁ICP备08000592号
Powered by Discuz, Processed in 0.056938 second(s), 9 queries.
Copyright©2004-2008, BCCN.NET, All Rights Reserved