单链表基础篇

来源:互联网 发布:淘宝实名认证小号购买 编辑:程序博客网 时间:2024/06/09 22:18

1.比较顺序表和链表的优缺点,说说它们分别在什么场景下使用?
1). 顺序表支持随机访问,单链表不支持随机访问。
2). 顺序表插入/删除数据效率很低,时间复杂度为O(N)(除尾插尾删),单链表插入/删除效率更高,时间复杂度为O(1)。
3). 顺序表的CPU高速缓存效率更高,单链表CPU高速缓存效率低。
2.从尾到头打印单链表

//递归法void PrintList(ListNode* plist){    if(plist==NULL)    {        return;    }    PrintList(plist->next);    printf("%d->",plist->data);}

3.删除一个无头单链表的非尾节点

void EraseNonTail(ListNode* pos){    assert(pos&&pos->next);    ListNode* next=pos->next;    pos->data=next->data;    pos->next=next->next;    free(next);}

4.在无头单链表的一个节点前插入一个节点

void InsertNonHead(ListNode* pos, DataType data){    assert(pos);    ListNode* next = pos->next;    ListNode* tmp = BuyNode(data);    pos->next = tmp;    tmp->next = next;    DataType datatmp = pos->data;    pos->data = tmp->data;    tmp->data = datatmp;}

5.单链表实现约瑟夫环

ListNode* JosephRing(ListNode* plist, int k){    //不带环返回空指针    if(IsCycle(plist) == NULL)    {        return NULL;    }    ListNode* cur = plist;    //只剩一个节点循环停止    while(cur != cur->next)    {        int count = k;        while(--count)          {            cur = cur->next;        }        ListNode* next = cur->next;        cur->data = next->data;        cur->next = next->next;        free(next);    }    return cur;}

6.逆置/反转单链表

ListNode* ReverseList(ListNode* plist){    ListNode* newhead = NULL;    ListNode* cur = plist;    ListNode* tmp = plist;    while(cur)    {        cur = cur->next;        tmp->next = newhead;        newhead = tmp;        tmp = cur;    }    return newhead;}

7.单链表排序(冒泡排序&快速排序)

void BubbleList(ListNode* plist){    ListNode* tail = NULL;    while(tail != plist->next)    {        ListNode* cur = plist;        ListNode* next = plist->next;        while(next != tail)        {            if(cur->data > next->data)            {                DataType tmp = cur->data;                cur->data = next->data;                next->data = tmp;            }            next = next->next;            cur = cur->next;        }        tail = cur;    }}

8.合并两个有序链表,合并后依然有序

ListNode* CombineList(ListNode* plist1, ListNode* plist2){    ListNode* list = NULL;    if(plist1 == NULL)    {        return plist2;    }    else if(plist2 == NULL)    {        return plist1;    }    else    {        if(plist1->data < plist2->data)        {            list = plist1;            plist1 = plist1->next;        }        else        {            list = plist2;            plist2 = plist2->next;        }        ListNode* tail = list;        while (plist1 && plist2)        {            if(plist1->data < plist2->data)            {                tail->next = plist1;                plist1 = plist1->next;                tail = tail->next;            }            else            {                tail->next = plist2;                plist2 = plist2->next;                tail = tail->next;            }        }        if(plist1 == NULL)        {            tail->next = plist2;        }        else        {            tail->next = plist1;        }    }    return list;}

9.查找单链表的中间节点,要求只能遍历一次链表

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

10.查找单链表的倒数第k个节点,要求只能遍历一次链表

ListNode* SearchListK_r(ListNode* plist, int k){    ListNode* fast = plist;    ListNode* slow = plist;    //fast往后走k-1步    int i = k;    for(i=0; i<k-1; i++)    {        fast = fast->next;        //如果k大于了链表长度,返回空指针        if(fast == NULL)        {            return NULL;        }    }    //让fast走到最后一个节点    while(fast->next)    {        fast = fast->next;        slow = slow->next;    }    return slow
原创粉丝点击