C语言实现单链表面试题——基础篇(中)

6.逆值/翻转单链表

思想同从头打印链表一样,但应注意在反向连接链表时的指向问题

void ListTranspose(ListNode **ppList,ListNode *pList)//转置单链表
  {
      assert(ppList);
      if((*ppList == NULL)||((*ppList)->next == NULL))
          return;
         //当链表没有节点和只有一个节点的时候,转置不改变
        if(pList->next != NULL) //
            ListTranspose(ppList,pList->next);
        else
        {
            *ppList = pList;//找到最后一个节点,并用头节点指向
            return;
        }
        (pList->next)->next  = pList; //
        pList->next = NULL;
  } 
7. 单链表排序(冒泡排序)

冒泡排序是两两比较,N个数,需要N-1趟,每一趟可以找出最大的数放在这一趟的最右边:这里写图片描述

void ListBubb(ListNode **ppList)//冒泡排序
{
    assert(ppList);
    if(*ppList == NULL)//链表为空时,直接返回
        return;
    ListNode *head = *ppList;//每次一趟从头节点开始
    ListNode *tail = NULL; //用于结束标志,每一趟后tail向前一个节点挪
     while((*ppList)->next != tail)
     {
         head = *ppList;
         while(head->next != tail)
         {
             if((head->data) > (head->next->data))
             {
                 DataType tmp = head->data;
                 head->data = head->next->data;
                 head->next->data = tmp;
             }
             head = head->next;
         }
         tail = head;
     }
}
8.合并两个有序链表,合并后依然有序

最简单的方法就是用第一个链表的尾部连上另一个链表头节点,再用冒泡排序:

ListNode* ListLink(ListNode **ppList_1,ListNode **ppList_2)
{
    assert(ppList_1&&ppList_2);
    ListNode *tail = *ppList_1;
    while(tail->next != NULL)
    {
        tail = tail->next;
    }
    tail->next = *ppList_2;
    ListBubb(ppList_1);
    return *ppList_1;
}

这里写图片描述
但这种方法时间复杂太大,有没有更好的办法呢?
先找两个链表第一个节点的小的头链表,然后在这链表后面插两两比较小的节点。直至其中一个链表遇到NULL;
这里写图片描述

//链接链表并排序
ListNode* ListLink(ListNode **ppList_1,ListNode **ppList_2)
{
    assert(ppList_1&&ppList_2);
    ListNode *pList_1  = *ppList_1;
    ListNode *pList_2 =  *ppList_2;
    if(pList_1->data > pList_2->data)//找到头节点小的链表
    {
        *ppList_1 = *ppList_2;
        pList_2 = pList_2->next;
    }
    else
    {
        pList_1 = pList_1->next;
    }
    ListNode *pList = *ppList_1;
    while(pList_1 && pList_2)
    {
        if(pList_1->data > pList_2->data)
        {
            pList->next = pList_2;
            pList_2 = pList_2->next;
        }
        else
        {
            pList->next = pList_1;
            pList_1 = pList_1->next;
        }
        pList = pList->next;
    }
    if(pList_1)//遇到NULL
    {
        pList = pList_2;
    }
    else
    {
        pList = pList_1;
    }
    return *ppList_1;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值