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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章