二:单链表的反转-递归和循环方式实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013139008/article/details/83242698

 单链表的创建、打印和释放见博客 一:单链表的创建、打印和释放

1. 递归方式实现单链表的反转

/**
 *@param pList NODE_t * :带头结点的单链表的第一个有效结点
 */
NODE_t * SListRecur(NODE_t *pFirst) {
    if (pFirst == NULL || pFirst->pNext == NULL) {
        return pFirst;
    }

    NODE_t *pNewNode = SListRecur(pFirst->pNext);
    pFirst->pNext->pNext = pFirst;
    pFirst->pNext = NULL;
    return pNewNode;
}

/**
 * 通过递归方式实现单链表的反转
 * 原来的单链表成为反转后的单链表
 *
 */
NODE_t * ReverseSListRecur(NODE_t *pList) {
    if (pList == NULL || pList->pNext == NULL) {
        printf("single list is empty\n");
        return pList;
    }

    NODE_t *pHead = pList;
    NODE_t *pNewHead = SListRecur(pHead->pNext);
    pHead->pNext = pNewHead;
    return pHead;
}

2. 循环方式实现单链表的反转

​​/**
 * 通过循环方式实现单链表的反转
 * 原来的单链表成为反转后的单链表
 *
 * @param pList NODE_t * :单链表的头结点
 */
NODE_t * ReverseSListCirle(NODE_t *pList) {
    if (pList == NULL || pList->pNext == NULL) {
        printf("single list is empty\n");
        return pList;
    }

    NODE_t *pHead = pList;
    NODE_t *pPre = pHead->pNext;
    NODE_t *pCur = pPre->pNext;
    NODE_t *pNext = NULL;
    /* 第一个有效结点的后继不设置为空,会造成无限循环 */
    pPre->pNext = NULL;

    /* 使用三个指针指示当前,前一个,后一个结点地址
       每次使当前、前一个结点反转,然后指针后移 */
    while (pCur != NULL) {
        pNext = pCur->pNext;
        pCur->pNext = pPre;
        pPre = pCur;
        pCur = pNext;
    }

    pHead->pNext = pPre;
    return pHead;
}

3. 测试代码

int main() {
    /* 创建单链表,递归遍历单链表 */
    int aArray[6] = { 1, 4, 5, 2, 1, 6 };
    NODE_t *pList1 = CreateArraySList(aArray, 6);
    ShowSList(pList1);
    NODE_t *pNew1 = ReverseSListRecur(pList1);
    ShowSList(pNew1);
    FreeSList(pList1);

    /* 创建单链表,循环遍历单链表 */
    NODE_t *pList2 = CreateArraySList(aArray, 6);
    ShowSList(pList2);
    NODE_t *pNew2 = ReverseSListCirle(pList2);
    ShowSList(pNew2);
    FreeSList(pList2);

    return 0;
}

猜你喜欢

转载自blog.csdn.net/u013139008/article/details/83242698
今日推荐