零基础学习数据结构与算法|2、链表

1、链表的定义

	n个节点离散存储,彼此通过指针相连,每个节点都有唯一的前驱节点和后继节点,
首节点没有前驱节点,尾节点没有后继节点。

专业名词

  • 首节点:第一个有效节点
  • 尾节点:最后一个有效节点
  • 头节点:第一个有效节点之前的节点,不存放任何有效数据,目的是为了方便对链表的操作
  • 头指针:指向头节点的指针
  • 尾指针:指向尾节点的指针

定义语句

typedef struct Node
{
    int data;           // 数据域
    struct Node *pNext; // 指针域,指向了和它数据类型相同的变量

} NODE, *PNODE; // NODE等价于struct Node,PNODE等价于typedef struct Node*

2、链表的分类

  1. 单链表
  2. 双链表:每一个节点有两个指针域,既可以指向前驱节点,又可以指向后继节点
  3. 循环链表:能通过任意一个节点,找到链表的其它所有节点
  4. 非循环链表

3、算法

1)创建链表
PNODE create_list(void)
{
    PNODE phead = (PNODE)malloc(sizeof(PNODE)); // 初始化头节点
    if (phead == NULL)
    {
        printf("初始化失败!");
        exit(-1);
    }
    PNODE pnode = phead;
    pnode->pNext = NULL;
    int len;
    printf("请用户输入链表的长度:\n");
    scanf("%d", &len);
    for (int i = 0; i < len; i++)
    {
        int val;
        PNODE pnew = (PNODE)malloc(sizeof(PNODE));
        printf("你想要输入链表第%d个元素的值是:\n", i + 1);
        scanf("%d", &val);
        pnew->data = val;
        pnode->pNext = pnew;
        pnew->pNext = NULL;
        pnode = pnew;
    }
    return phead;
}
2)遍历链表
void traverse_list(PNODE phead)
{
    PNODE pnode = phead->pNext;
    while (pnode != NULL)
    {
        printf("%d ", pnode->data);
        pnode = pnode->pNext;
    }
    printf("\n");
}

在这里插入图片描述

3)判空
bool isempty(PNODE phead)
{
    if (phead->pNext == NULL)
        return true;
    else
        return false;
}
4)求链表的长度
int length(PNODE phead)
{
    int count = 0;
    PNODE pnode = phead->pNext;
    while (pnode != NULL)
    {
        count++;
        pnode = pnode->pNext;
    }
    return count;
}
5)链表排序
void sort_list(PNODE phead)
{
    int len = length(phead);
    for (PNODE pnode = phead->pNext; pnode != NULL; pnode = pnode->pNext)
    {
        int t;
        for (PNODE qnode = pnode->pNext; qnode != NULL; qnode = qnode->pNext)
        {
            if (pnode->data > qnode->data)
            {
                t = pnode->data;
                pnode->data = qnode->data;
                qnode->data = t;
            }
        }
    }
    return;
}

6)在指定位置前插入一个元素
bool insert_element(PNODE phead, int pos, int val)
{
    int i = 0;
    PNODE pnew = (PNODE)malloc(sizeof(NODE));
    if (pnew == NULL)
        printf("动态分配内存失败!");
    pnew->data = val;
    PNODE pnode = phead;
    while (i < pos - 1 && pnode != NULL)//找到插入元素的前驱节点
    {
        i++;
        pnode = pnode->pNext;
    }
    if (i > pos - 1 || pnode == NULL)
        return false;
    pnew->pNext = pnode->pNext;
    pnode->pNext = pnew;
    return true;
}
7)删除指定位置的元素
bool delete_element(PNODE phead, int pos, int *val)
{
    int i = 0;
    PNODE pnode = phead;
    while (i < pos - 1 && pnode->pNext != NULL)//找到删除元素的前驱节点
    {
        i++;
        pnode = pnode->pNext;
    }
    if (i > pos - 1 || pnode->pNext == NULL)
        return false;
    PNODE p = pnode->pNext;
    *val = p->data;
    pnode->pNext = pnode->pNext->pNext;
    free(p);

    return true;
}

main函数

int main()
{
    int val;
    PNODE phead;
    phead = create_list();
    traverse_list(phead);
     if (isempty(phead))
      {
          printf("该链表为空\n");
      }
      else
          printf("该链表不为空!\n");
      int len = length(phead);
      printf("该链表的长度为%d\n", len);
    sort_list(phead);
    traverse_list(phead);
    insert_element(phead, 2, 55);
    traverse_list(phead);
    delete_element(phead, 2, &val);
    traverse_list(phead);

    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值