两种方法实现链表的节点操作排序

题目:

功能: 根据单向链表的节点值和排序标识进行升降排序,并返回排序后的链表头指针。

输入: ListNode* pListHead  单向链表
unsigned int uiSortFlag  0表示按升序,1表示按降序

输出: 无

返回: 排序成功返回链表头指针,异常或未进行排序返回空指针


  说明:通过四个指针实现两个节点的交换,也即要保持该交换的节点的前后节点

源码如下:

/*
功能: 根据单向链表的节点值和排序标识进行升降排序,并返回排序后的链表头指针。

输入: ListNode* pListHead  单向链表
unsigned int uiSortFlag  0表示按升序,1表示按降序

输出: 无

返回: 排序成功返回链表头指针,异常或未进行排序返回空指针
*/

struct ListNode
{
    int       m_nKey;
	ListNode* m_pNext;
};

ListNode* SortList(ListNode* pHead, unsigned int uiSortFlag)
{
    /*需要四个节点*/
    ListNode *p;        /*要交换的节点之前的节点 */
    ListNode *prep;     /*要加换的第一个节点*/
    ListNode *temp;     /*要交换的第二个节点*/
    ListNode *tail;     /*第二个节点后的节点*/ 
    ListNode *pTempNode; /*用于指向创建的头文件*/
    ListNode pHeadNode;  /*对于没有头结点的链表,需要自己创建一个头结点,方便后面的操作*/
    pHeadNode.m_nKey = 0;
    pHeadNode.m_pNext = pHead;
    pTempNode = &pHeadNode;
    tail = (ListNode *)NULL;

    if (pHead == NULL)/
    {
        return (ListNode *)NULL;
    }
    if (uiSortFlag != 0 && uiSortFlag != 1)
    {
        return (ListNode *)NULL;
    }
    // 算法的核心部分
    switch(uiSortFlag)
    {
    case 0:
        /*关键处理部分*/
        while( pTempNode->m_pNext != tail )
        {
            prep = pTempNode;
            p = pTempNode->m_pNext;
            while( p->m_pNext != tail )
            {
                if( p->m_nKey > p->m_pNext->m_nKey )
                {
                    temp = p->m_pNext;
                    prep->m_pNext = p->m_pNext;
                    p->m_pNext = p->m_pNext->m_pNext;
                    prep->m_pNext->m_pNext = p;
                    p = temp;
                }
                // 节点后移
                p = p->m_pNext;
                prep = prep->m_pNext;
            }
            tail = p;
        }// 第一个while
        break;
    case 1:
        while( pTempNode->m_pNext != tail )
        {
            prep = pTempNode;
            p = pTempNode->m_pNext;
            while( p->m_pNext != tail )
            {
                if( p->m_nKey < p->m_pNext->m_nKey )
                {
                    temp = p->m_pNext;
                    prep->m_pNext = p->m_pNext;
                    p->m_pNext = p->m_pNext->m_pNext;
                    prep->m_pNext->m_pNext = p;
                    p = temp;
                }
                // 节点后移
                p = p->m_pNext;
                prep = prep->m_pNext;
            }
            tail = p;
        }// 第一个while
        break;
    default:
        return (ListNode *)NULL;
    }
	return pHeadNode.m_pNext;
}

int mian(int argc, char* argv[])
{
     ListNode astListNode[6];
    ListNode *pListHead;
    ListNode *pListNext;

    astListNode[0].m_nKey = 1;
    astListNode[0].m_pNext = &astListNode[1];

    astListNode[1].m_nKey = 3;
    astListNode[1].m_pNext = &astListNode[2];

    astListNode[2].m_nKey = 2;
    astListNode[2].m_pNext = &astListNode[3];

    astListNode[3].m_nKey = 1;
    astListNode[3].m_pNext = &astListNode[4];

    astListNode[4].m_nKey = 5;
    astListNode[4].m_pNext = &astListNode[5];

    astListNode[5].m_nKey = 4;
    astListNode[5].m_pNext = NULL;

    pListHead = SortList(astListNode, 1);
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值