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;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值