c語言實現簡單單鏈表

1.比較順序表和鏈表的優缺點,說說他們正在什麼場景下使用?
答:
對於順序表,無論是動態還是靜態,他們有都會死連續的存儲空間,在讀取時間效率上比較短,但在插入和刪除時會比較麻煩,需要不斷的遍歷去找到尾節點。
對於鏈表,因爲是鏈式存儲。因此在需要的時候我們纔在堆上進行開闢空間,鏈表對於插入刪除比較簡單,但是遍歷需要多次跳轉。
對於空間申請方式:
順序表,空間開闢是在順序表空間已滿時開闢,開闢次數較多時會出現較大的空間浪費。
對於鏈表,空間是針對單個節點的,不存在多餘的空間浪費。並且在碎片空間池的機制下,有效利用碎片空間。
所以,順序表一般用於查找遍歷操作比較頻繁的情況下進行使用,鏈表則針對於數據刪除修改比較頻繁的數據使用。
2.從未到頭打印單鏈表

void PrintNodeTailToHead(ListNode *head)
{
    if (head)
    {
        while (head->next)
        {
            PrintNodeTailToHead(head->next);
        }
    }
    printf("%d->",head->data);
}

3.刪除一個無頭單鏈表的非尾節點

void DelNoTail(ListNode*plist)
{
    ListNode*del = plist->next;
    plist->data = del->data;
    plist->next = del->next;
    free(plist);
    plist = NULL;
}

4.在無頭單鏈表的一個節點前程插入一個節點

void Insert(ListNode** ppList, ListNode* pos, DataType x)
{
    if ((*ppList) == NULL)
    {
        *ppList = BuyNode(x);
    }
    else
    {
        ListNode *cur = BuyNode(x);
        cur->next = pos->next;
        pos->next = cur;
    }
}

5.單鏈表實現約瑟夫環

DataType JLink(ListNode**pplist)
{
    ListNode *cur = *pplist;
    while ((*pplist)->next)
    {
        ListNode *del = *pplist;
        del = (*pplist)->next->next->next;
        *pplist = del;
        free(del);
        del = NULL;
    }
    return (*pplist)->data;
}

6.逆置/ 反轉單鏈表

void _Reversre(ListNode*plist)//遞歸
{
    ListNode *cur = plist;
    ListNode *prev = plist;
    while (cur->next)
    {
        prev = cur;
        cur = cur->next;
    }
    cur->next = prev;
}
void reverse(ListNode**listhead)//非遞歸
{
    if ((NULL == (*listhead)) || (NULL == ((*listhead)->next)))
        return;  //邊界檢測  
    ListNode* ppre = *listhead;    //先前指針  
    ListNode* pcur = ppre->next;  //當前指針  
    ListNode* pnext = NULL;       //後繼指針  
    while (pcur != NULL)
    {
        pnext = pcur->next;
        pcur->next = ppre;
        ppre = pcur;
        pcur = pnext;
    }
    (*listhead)->next = NULL;
    (*listhead) = ppre;        //記錄下新的頭結點  
}

7.單鏈表排序(冒泡排序)

void sort(ListNode*plist)
{
    //冒泡
    ListNode *max=plist;
    DataType tmp;
    while (max->next)
    {
        if ((max->data) < plist->data)
        {
            tmp = max->data;
            max->data = plist->data;
            plist->data = tmp;
        }
        else
            plist = plist->next;
        if (plist->next == NULL)
        {
            max = max->next;
        }
    }
}

8.合併兩個有序鏈表,合併後依然有序

ListNode Merge(ListNode* head1, ListNode* head2)
{
    ListNode* newhead = NULL;
    if (head1->data < head2->data)
    {
        newhead = head1;
        head1 = head1->next;
        newhead->next = Merge(head1, head2);
    }
    if (head1->data>head2->data)
    {
        newhead = head2;
        newhead->next = Merge(head1, head2->next);
    }
}

9.查找單鏈表的中間節點,要求只遍歷一遍

ListNode FindMid(ListNode*plist)
{
    ListNode *slow = plist;
    ListNode *fast = plist;
    while (fast)
    {
        fast = fast->next->next;
        slow = slow->next;
    }
    return *slow;
}

10.查找單鏈表的倒數第K個節點,要求只遍歷一遍

ListNode FindReNum(ListNode*plist, int k)
{
    ListNode*fast = plist;
    ListNode*slow = plist;
    while (k--)
    {
        fast=fast->next;
    }
    while (fast)
    {
        fast = fast->next;
        slow = slow->next;
    }
    return *slow;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章