单链表的基本操作大全之C语言实现(二)

本文介绍使用C语言实现的单链表高级操作,包括递归打印、快速排序、链表长度计算、链表反转、有序链表合并、查找中间节点、检测环等,并提供详细的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

单链表的基本操作大全之C语言实现(二)

补充一些链表的操作,之前的基本操作点击下面的链接。
单链表的基本操作大全之C语言实现(一)

1. 递归打印链表

void show_linklist(PNODE *phead) 
{
        if(phead == NULL){
                return;
        }else{
                printf("%d\t", phead->data);
                show_linklist(phead->pnext);
                //将此行放在printf的前面则递归打印倒置链表
        }
}

2.链表快速排序

PNODE *divide_two_Qsort(PNODE *phead, PNODE *ptail)
{
        int key = phead->data;
        PNODE *p = phead;
        PNODE *q = phead->pnext;

        while(q != ptail){ 
                if(q->data < key){
                        p = p->pnext;
                        int tmp;
                        tmp = p->data;
                        p->data = q->data;
                        q->data = tmp;
                }       
                q = q->pnext;
        }
        int tmp = p->data;
        p->data = phead->data;
        phead->data = tmp;

        return p;
}

void quicksort_linklist(PNODE *phead, PNODE *ptail)
{
        if(phead != ptail){
                PNODE *pmid = divide_two_Qsort(phead, ptail);
                quicksort_linklist(phead, pmid);
                quicksort_linklist(pmid->pnext, ptail);
        }
}

3. 递归计算链表长度

int getlistlen_recursion(PNODE *phead)
{
        if(phead == NULL)
                return 0;
        else
                return 1+getlistlen_recursion(phead->pnext);
}

4.反转链表(非递归)

PNODE *invert_linklist(PNODE *phead)
{
        if(phead == NULL || phead->pnext == NULL){
                return phead;
        }else{
                PNODE *p = phead;
                PNODE *q = NULL;
                PNODE *r = NULL;
                while(p != NULL){
                        q = p->pnext;//保存下一个节点
                        p->pnext = r;//让该节点指向上一个节点
                        r = p;//上一个节点走到当前节点
                        p = q;//当前节点走到下一个节点
                }
                return r;
        }
}

5.反转链表(递归)

PNODE *invert_linklist_recursion(PNODE *phead)
{
        if(phead == NULL || phead->pnext == NULL){
                return phead;
        }else{
                PNODE *p = phead;//保存头节点
                PNODE *q = p->pnext;//保存下一个节点
                phead = invert_linklist_recursion(q);//递归到最后一个几点,返回转置后链表的地址
                q->pnext = p;//让后面的节点指向前一个节点
                p->pnext = NULL;//每次递归返回都赋值为空,最后一次返回将转置后的节点的pnext赋值为空
                return phead;
        }
}

6.合并两个有序链表(非递归)

PNODE *merge_linklist(PNODE *phead1, PNODE *phead2)
{
        if(phead1 == NULL){
                return phead2;
        }else if(phead2 == NULL){
                return phead1;
        }

        PNODE *phead = NULL;

        if(phead1->data < phead2->data){
                phead = phead1;
                phead1 = phead1->pnext;
        }else{
                phead = phead2;
                phead2 = phead2->pnext;
        }//让phead找到最小的头节点

        PNODE *pcur = phead;//要比较节点(phead1 或 phead2)的上一个节点
        while(phead1 != NULL && phead2 != NULL){
                if(phead1->data < phead2->data){
                        pcur->pnext = phead1;
                        pcur = phead1;
                        phead1 = phead1->pnext;
                }else{
                        pcur->pnext = phead2;
                        pcur = phead2;
                        phead2 = phead2->pnext;
                }
        }

        pcur->pnext = ((phead1 == NULL) ? phead2 : phead1);

        return phead;
}

7.合并两个有序链表(递归)

PNODE *merge_linklist_recursion(PNODE *phead1, PNODE *phead2)
{
        if(phead1 == NULL){
                return phead2;  
        }else if(phead2 == NULL){
                return phead1;
        }       
        PNODE *phead = NULL;
        if(phead1->data < phead2->data){
                phead = phead1;
                phead->pnext = merge_linklist_recursion(phead1->pnext, phead2);
        }else{  
                phead = phead2;
                phead->pnext = merge_linklist_recursion(phead1, phead2->pnext);
        }
        return phead;
}

8.找到链表中间节点

PNODE *find_midnode(PNODE *phead)
{
        if(phead == NULL || phead->pnext == NULL){
                return phead;
        }

        PNODE *p1 = phead;
        PNODE *p2 = phead;
        while(p2->pnext != NULL){
                p1 = p1->pnext;//p1走一步
                p2 = p2->pnext;
                if(p2->pnext != NULL){
                        p2 = p2->pnext;//p2走两步
                }
        }
        return p1;
}

9.判断链表是否有环

int is_circularlinklist(PNODE *phead)
{
        if(phead == NULL || phead->pnext == NULL){
                return 0;       
        }
        PNODE *p1 = phead;
        PNODE *p2 = phead;
        while(p1 != NULL && p2 != NULL){
                p2 = p2->pnext; 
                if(p1 == p2)
                        return 1;
                p2 = p2->pnext;
                p1 = p1->pnext;
        }
        return 0;
}

10.释放链表

void destory_linklist(PNODE *phead) 
{
        PNODE *ptmp;
        while(phead != NULL){
                ptmp = phead;
                phead = phead->pnext;
                free(ptmp);
                ptmp = NULL;
        }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值