c语言链表详解

c语言链表

一、单链表(不带头结点的单向不循环链表)

1. 链表的特点

  • n个节点离散分配
  • 每一个节点之间通过指针相连
  • 每一个节点有一个前驱节点和一个后继节点
  • 首节点没有前驱节点,尾节点没有后继节点
    【定义一个简单的结构体】
typedef struct link{
    int data;//定义数据域
    struct link *next;//定义指针域,存储直接后继节点信息
}Link;
  • 数据域的内容可以自己来指定,指针域用于存放下一个节点的地址

2. 创建链表前须知

  • 首节点:存放第一个有效数据的节点
  • 头节点:在单链表的第一个节点之前附设一个节点,没有直接前驱,头节点的数据域可以不存储任何信息,指针域指向第一个节点的地址。头节点的作用是使所有链表的头指针非空。
  • 头指针:指向头节点的指针
  • 尾节点:存放最后一个有效数据的节点
  • 尾指针:指向尾节点的指针

3. 创建单链表

  • 代码
Link *create(Link *phead, int size)
{
    phead = (Link *)malloc(sizeof(Link));//头节点没有值
    Link *end = phead;//定义尾指针指向头指针
    end->next = NULL;//尾指针指向NULL
    Link *p = NULL;//定义新节点的指针
    int i = 0;
    int data;
    while(i<size)
    {
        scanf("%d",&data);
        p = (Link *)malloc(sizeof(Link));//创建普通结点
        p->data = data;
        end->next = p;
        p->next = NULL;
        end = p;
        i++;
    }
    return phead;
}
  • 图解

4. 增加结点

  • 代码
Link *add_Node(Link *phead, int size, int value)
{
    Link *p = phead->next;
    Link *Node = (Link *)malloc(sizeof(Link));//给新结点分配空间
    int i = 0;
    while(p!=NULL)
    {
        i++;
        if(i == size)
        {
            Node->data = value;//赋值给新结点
            Node->next = p->next;//把新结点的指针指向当前结点的下一个结点
            p->next = Node;//将当前结点的指针指向新结点
            break;
        }
        p = p->next;
    }
    return phead;
}
  • 图解

5. 删除结点

  • 代码
Link *delete_Node(Link *phead, int size)
{
    Link *p = phead->next;
    int i = 0;
    while(p!=NULL)
    {
        i++;
        if(i == size)
        {
            p->next = p->next->next;//没有释放空间
            free(p);//回去做验证
            break;
        }
        p = p->next;
    }
    return phead;
}
  • 图解

6. 查询结点

  • 代码
Link *research_Node(Link *phead, int size)
{
    Link *p = phead->next;
    int i = 0;
    while(p!=NULL)
    {
        i++;
        if(i == size)
        {
            printf("第%d个位置的值是: %d\n\n",i,p->data);
            break;
        }
        p = p->next;
    }
    return phead;
}
  • 图解

7. 修改结点

  • 代码
Link *transfor_Node(Link *phead, int size, int value)
{
    Link *p = phead->next;
    int i = 0;
    while(p!=NULL)
    {
        i++;
        if(i == size)
        {
            p->data = value;//将当前结点的指针指向新结点
            break;
        }
        p = p->next;
    }
    return phead;
}
  • 图解

7. 排序

  • 代码
//链表的排序--冒泡排序法 --按照自己的方式--时间复杂度为:f(n) = n*n
Link *Sort_List(Link* pHead )
{
    Link *p = pHead->next;
    Link *p1 = NULL;
    while(p!=NULL)
    {
        p1=pHead;
        while(p1->next!=NULL)
        {
            if(p1->next->data > p1->data)
            {
                int data;
                data = p1->next->data;
                p1->next->data = p1->data;
                p1->data = data;
            }
            p1 = p1->next;
        }
        p = p->next;
    }
    return pHead;
}
  • 图解

8.遍历链表

  • 代码
void print(Link *head)
{
    Link *p = head->next;
    while(p!=NULL)//回去验证一下这个地方
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
}
  • 图解

二、单循环链表

  • 循环链表是一种头尾相接的链表(就是最后一个结点的指针指向第一个节点)
  • 优点:从表中任意一节点出发都可以找到表中其他节点
  • 注意:循环链表中没有NULL指针,故遍历链表时,其终止条件是判断是不是等于头指针。

【1. 循环链表的创建】

  • 结构体创建
typedef struct link{
    int data;//定义数据域
    struct link *next;//定义指针域
}Link;
  • 循环链表创建
Link *create(Link *phead, int size)
{
    phead = (Link *)malloc(sizeof(Link));//头节点没有值
    Link *p = phead;//指向头指针
    p->next = p;
    Link *p1 = NULL;//定义新节点的指针
    int i = 0;
    int data;
    while(i<size)
    {
        scanf("%d",&data);
        p1 = (Link *)malloc(sizeof(Link));//创建新节点、分配新的空间
        p1->data = data;
        p->next = p1;
        p1->next = phead;
        p = p1;
        i++;
    }
    return phead;
}
  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值