数据结构:简单链表的常见使用方法

在初学数据结构时,我第一次接触链表。作为一个初学C语言的小白,在我的认知里链表是一个可以被数组取代的鸡肋的东西。然而在深度学习链表之后,我发现链表在对数据的一些操作处理的时候会比数据更加方便,更有效率。现在我将我所了解的链表的功能分享出来供大家参考讨论,如有错误或补充,还请大家指出批评,我会积极学习并更改。

链表是一种存储结构,用来存储数据元素。它是由若干个节点组成,而所存数据的逻辑顺序是和节点顺序一样的。在链表中,每一个节点都是由数据域和指针域所构成,数据域存放的是该节点的数据元素,指针域存放的是该节点后一个节点的地址。这样做的好处是,相邻的数据在存储单元可以是连续的,也可以是不连续的,在查找数据元素时,也比顺序表效率高了很多。

typedef int datatype;

typedef struct Node         //结点类型的创建
{
	datatype data;
	struct Node* next;
}Node,*pNode,List,*pList;

链表一些常见的使用如下

  • void InitLinkList(pList* pplist);                             //初始化链表

void InitLinkList(pList* pplist)  
{

    assert(pplist != NULL);
    if (*pplist = NULL)
    {
        return;
    }
    else
    {
        pList cur = *pplist;
        pList cur2 = NULL;
        while (cur)
        {
            cur2 = cur->next;
            free(cur);
            cur = cur2;
        }
        *pplist = NULL;
    }
    return;
}
 

  • pNode BuyNode(datatype d);                                    //在链表中创建一个新节点

pNode BuyNode(datatype d)
{
    pNode newnode;
    newnode = malloc(sizeof(Node));
    newnode->data = d;
    newnode->next = NULL;
    return newnode;
}

  • void DestroyLinkList(pList* pplist);                          //注销一个链表

void DestroyLinkList(pList* pplist)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    pList cur2 = NULL;
    while (cur)
    {
        cur2 = cur->next;
        free(cur);
        cur = cur2;
    }
    *pplist = NULL;
    return;
}

  • void PushBack(pList* pplist, datatype d);                     //尾部插入一个新节点

void PushBack(pList* pplist, datatype d)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    if (cur == NULL)
    {
        *pplist = BuyNode(d);
        return;
    }
    while (cur->next)
    {
        cur = cur->next;
    }
    cur->next = BuyNode(d);
    return;
}
 

  • void printLinkList(pList* pplist);                            //打印一个链表

void printLinkList(pList* pplist)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    while (cur)
    {
        printf("%d ", cur->data);
        cur = cur->next;
    }
    printf("\n");
    return;
}
 

  • void PopBack(pList* pplist);                                  //尾部弹出一个节点

void PopBack(pList* pplist)
{
    assert(pplist!= NULL);
    pList cur = *pplist;
    if (cur == NULL)
    {
        return;
    }
    else if (cur->next == NULL)
    {
        free(cur);
        *pplist = NULL;
        return;
    }
    else
    {
        while (cur->next->next)
        {
            cur = cur->next;
        }
        free(cur->next);
        cur->next = NULL;
    }
    return;
}

  • void PushFront(pList* pplist, datatype d);                    //头部插入一个新节点

void PushFront(pList* pplist, datatype d)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    if (cur == NULL)
    {
        *pplist = BuyNode(d);
        return;
    }
    else
    {
        *pplist = BuyNode(d);
        (*pplist)->next = cur;
    }
    return;
}

  • void PopFront(pList* pplist);                                 //头部弹出一个节点

void PopFront(pList* pplist)
{
    assert(pplist != NULL);
    if (*pplist == NULL)
    {
        return;
    }
    else if ((*pplist)->next == NULL)
    {
        free(*pplist);
        *pplist = NULL;
    }
    else
    {
        pList cur = (*pplist)->next;
        free(*pplist);
        *pplist = cur;
    }
    return;
}

  • pNode find(pList plist, datatype d);                          //根据数据找到节点

pNode find(pList plist, datatype d)
{
    pList cur = plist;
    while (cur != NULL)
    {
        if (cur->data == d)
        {
            return cur;
        }
        cur = cur->next;
    }
    return NULL;
}

  • void Insert(pList* pplist, pNode pos, datatype d);            //在给定数据前加入一个新节点

void Insert(pList* pplist, pNode pos, datatype d)
{
    assert(pplist != NULL);
    pNode new = BuyNode(pos->data);
    if (pos == NULL)
    {
        free(new);
        return;
    }
    new->next = pos->next;
    pos->next = new;
    pos->data = d;
    return;
}

  • void Erase(pList* pplist, pNode pos);                         //删除一个给定位置的节点

void Erase(pList* pplist, pNode pos)
{
    assert(pplist != NULL);
    if (pos == NULL)
        return;
    pNode cur = pos;
    while (cur->next->next != NULL)
    {
        cur->data = cur->next->data;
        cur = cur->next;
    }
    cur->data = cur->next->data;
    free(cur->next);
    cur->next = NULL;
    return;
}

  • void Remove(pList* pplist, datatype d);                       //移除给定数据的节点(1个)

void Remove(pList* pplist, datatype d)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    while (cur != NULL)
    {
        if (cur->data == d)
        {
            Erase(pplist, cur);
            return;
        }
        cur = cur->next;
    }
    return;
}

  • void RemoveAll(pList* pplist, datatype d);                    //移除给定数据的节点(全部)

void RemoveAll(pList* pplist, datatype d)
{
    assert(pplist != NULL);
    pList cur = *pplist;
    while (cur != NULL)
    {
        if (cur->data == d)
        {
            Erase(pplist, cur);
            continue;
        }
        cur = cur->next;
    }
    return;
}
 

  • void EraseNotTailNode(pNode pos);                             //移除一个非头节点

void EraseNotTailNode(pNode pos)    
{
    assert(pos->next != NULL);
    pList cur = pos->next;
    pos->data = cur->data;
    pos->next = cur->next;
    free(cur);
    cur = NULL;
    return;
}

  • int GetListLength(pList plist);                               //链表的长度

int GetListLength(pList plist)
{
    int i = 0;
    pList cur = plist;
    while (cur)
    {
        i++;
        cur = cur->next;
    }
    return i;
}

  • void PrintTailToHead(pList plist);                            //倒序打印链表

void PrintTailToHead(pList plist)   //  从未到头打印单链表(递归)
{
    if (plist == NULL)
        return;
    pList cur = plist;
    if (cur->next != NULL)
        PrintTailToHead(cur->next);
    printf("%d ", cur->data);
    return;
}

  • void InsertNode(pList* pplist, pNode pos, datatype d);
  • pNode JC(pList* pplist, int num);                             //用链表解决约瑟夫环问题

pNode JC(pList* pplist, int num)   //单链表实现约瑟夫环
{
    int i = 0;
    assert(pplist != NULL);
    pList cur = *pplist;
    pList cur1 = *pplist;
    while (cur->next != NULL)
    {
        cur = cur->next;
    }
    cur->next = cur1;
    while (cur1->next != cur1)
    {
        i = num;
        cur = cur1;
        while (--i)
        {
            cur = cur->next;
        }
        cur1 = cur;
        cur= cur1->next;
        cur1->data = cur->data;
        cur1->next = cur->next;
        free(cur);
    }
    return cur1;
}

  • void ReverseList(pList* pplist);                              //让链表倒序

void ReverseList(pList* pplist)   //逆置单链表
{
    assert(pplist != NULL);
    if ((*pplist == NULL) && ((*pplist)->next == NULL))
        return;
    pList cur1 = *pplist;
    pList cur2 = cur1->next;
    pList cur = NULL;
    cur1->next = NULL;
    while (cur2 != NULL)
    {
        cur = cur2->next;
        cur2->next = cur1;
        cur1 = cur2;
        cur2 = cur;
    }
    *pplist = cur1;
    return;
}

  • void BubbleSort(pList * pplist);                              //链表数据的有序排列

void BubbleSort(pList * pplist)    // 单链表排序(冒泡)
{
    assert(pplist != NULL);
    pList cur1 = *pplist;
    pList cur = *pplist;
    while (cur->next != NULL)
    {
        cur = cur->next;
    }
    while (cur1->next != cur)
    {    
        pList cur2 = cur1;
        while (cur2->next != cur)
        {
            if ((cur2->data) > (cur2->next->data))
            {
                datatype a = cur2->data;
                cur2->data = cur2->next->data;
                cur2->next->data = a;
            }
            cur2 = cur2->next;
        }
        cur = cur2;
    }
    return;
}
 

  • pNode Merge(pList* list1, pList* list2);                      //有序排列两个有序链表

pNode Merge(pList* list1, pList* list2)   //合并两个有序单链表
{
    pList cur = NULL;
    pList cur1 = NULL;
    pList cur2 = NULL;
    pList cur11 = NULL;
    if (((*list1)->data) < ((*list2)->data))
    {
        cur1 = *list1;
        cur2 = *list2;
    }
    else
    {
        cur1 = *list2;
        cur2 = *list1;
    }
    cur11 = cur1->next;
    cur = cur1;
    while (cur2 != NULL && cur11 != NULL)
    {
        if (cur2->data <= cur11->data)
        {
            pList cur22 = cur2->next;
            cur1->next = cur2;
            cur2->next = cur11;
            cur1 = cur2;
            cur2 = cur22;
        }
        else
        {
            cur1 = cur1->next;
            cur11 = cur11->next;
        }
    }
    if (cur1->next == NULL)
    {
        cur1->next = cur2;
    }
    return cur;
}

  • pNode FindMidNode(pList* head);                               //找到链表的中间数据

pNode FindMidNode(pList* head)   //查找单链表的中间节点,遍历一遍
{
    assert(head != NULL);
    pList cur1 = * head;
    pList cur2 = * head;
    while (cur2->next != NULL && cur2 != NULL)
    {
        cur1 = cur1->next;
        cur2 = cur2->next->next;
    }
    return cur1;
}
 

  • pNode CheckCycle(pList plist);                           //判断是否为带环链表以及找到环入口

pNode CheckCycle(pList plist)
{
    pList cur1 = plist;
    pList cur2 = plist;
    if (plist->next == NULL && plist->next->next == NULL)
    {
        return NULL;
    }
    cur1 = plist->next;
    cur2 = plist->next->next;
    while (cur1 != cur2)
    {
        if (cur1->next == NULL && cur2->next == NULL && cur2->next->next == NULL)
        {
            return NULL;
        }
        cur1 = cur1->next;
        cur2 = cur2->next->next;
    }
    cur1 = plist;
    while (cur1 != cur2)
    {
        cur1 = cur1->next;
        cur2 = cur2->next;
    }
    return cur1;
}

 

 

 

 

 

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值