Linux C 数据结构 (单向链表)

一、单向链表

        节点中只包含一个指针,用来指向相邻节点

1. 创建节点

//设计节点
typedef struct node
{
    int data;           //数据域
    struct node * next; //指针域
}Node , *Plist;

         定义一个名为node的结构体,用于表示链表的节点。结构体中包含两个成员:整型变量data作为数据域,存储节点数据;一个指向 node 类型结构体指针next作为指针域,指向下一个节点NodePlist别名 分别表示 struct node 和 struct node* 类型。

2. 初始化一个 空链表 (带头的)

//初始化空链表
Plist Init_list()
{
    Plist head = malloc(sizeof(Node));
    if(NULL == head)
    {
        perror("malloc");
        return NULL;
    }
    head->next = NULL;
    return head;
}

        创建并返回一个空 链表头(头节点)。链表头是链表的起始节点,指向链表第一个元素。使用malloc() 函数为 链表头分配内存空间,分配失败输出错误信息(#include <errno.h>)返回NULL。将链表头部的 next指针 指向NULL,表示链表目前是空的。函数返回链表头的指针。

sizeof(Node)        //struct node的别名

(不带头):Plist head = NULL;

3. 新建节点

//创建节点
Plist Init_node(int data)
{
    Plist head = malloc(sizeof(Node));
    if(NULL == head)
    {
        perror("malloc");
        return NULL;
    }
    head->next = NULL;
    head->data = data;
    return head;
}

多了一个 data 而已; 

4. 插入节点

//插入节点--后插 node后面
void Insert_node_back(Plist new , Plist node)
{
    new->next = node->next; //把new 和 node 后面的连接
    node->next = new;
}

//插入节点--前插
void Insert_node_front(Plist new , Plist node , Plist head)
{
    Plist prve = head;//定义 prev 为头节点

    while(prve->next != node)//寻找目标节点
        prve = prve->next;  

    Insert_node_back(new , prve);
}

//插入节点--头插
void Insert_node_head(Plist new , Plist head)
{
    new->next = head->next;//连接
    head->next = new;      
}

//插入节点--尾插
void Insert_node_back(Plist new , Plist node)
{
    Plist temp = head;
    while(temp->next != NULL)//没到 尾巴
        temp = temp->next;
 
    new->next = NULL;
    temp->next = new;
}

        刚开始没理解前插 和 后插 哪里是前 哪里是后 next后 pre前面;

        在链表的数据结构中,即使是空链表,通常也会有一个头节点。头节点是链表的起始点,即使链表中没有其他节点,头节点也是存在的。它的作用是为了简化对链表的操作,比如插入和删除节点时,从头节点开始处理更加方便;

5. 移除节点

void del_node(Plist head ,Plist node)
{
    //空链表
    if(Empty_list(head))
        return;

    //找到目标节点的上一个节点prev
    Plist prev = head;
    while (prev)
    {
        if(prev->next == node)
        {
            //让prev的next指向目标节点的下个节点
            prev->next = node->next;
            // prev->next = prev->next->next;
            //断开目标节点
            node->next = NULL;
            break;
        }
        prev = prev->next;
    }
}

 node前 指 node下一个;         node-> null ;

6.  查找

Plist find_node(Plist head ,int data)
{
    //空链表
    if(Empty_list(head))
        return NULL;
    
    Plist temp = head->next;

    while (temp)//只要不为空
    {
        if(temp->data == data)    //找到
            return temp;

        temp = temp->next;
    }
    return NULL;
}

 7.  移动节点

//移动节点
void move_node(Plist head ,Plist node , Plist dest)
{
    if(NULL == head || node == NULL || dest==NULL)
        return;

    del_node(head , node);
    Insert_node(node , dest);
}

8.  遍历链表

void show_list(Plist head)
{
    //空链表
    if(Empty_list(head))
        return;
    
    Plist temp = head->next;
    while (temp)
    {
        printf("%d->" , temp->data);
        temp = temp->next;
    }
    printf("\n");
}

 9.  判断是否为空链表

//判断是否是空链表  true:空链表 false:非空
bool Empty_list(Plist head)
{
    return head->next == NULL;
}

10.  销毁链表

//销毁链表
void rm_list(Plist head)
{
    if(NULL == head)
        return;

    Plist temp,node;
    node = head;

    while (1)
    {
        temp = node->next;//头的下一个
        free(node);//
        node = temp;//向后移动一位

        if(temp == NULL)
            break;
    }
    
    printf("销毁成功\n");
}

二、单向循环链表

1.  初始化链表

//初始化链表
Plist Init_list()
{
    Plist head = malloc(sizeof(Node));
    if(NULL == head)
    {
        perror("malloc");
        return NULL;
    }
    head->next = head;
    return head;
}

        自己指向自己 

2.  新建节点

//创建节点
Plist Init_node(int data)
{
    Plist head = malloc(sizeof(Node));
    if(NULL == head)
    {
        perror("malloc");
        return NULL;
    }
    head->next = head;
    head->data = data;
    return head;
}

3.  判断链表是否为空

4.  遍历链表

//遍历链表
void show_list(Plist head)
{
    if(NULL == head||Empty_list(head))
        return;
    
    Plist temp = head->next;
    while (temp!=head)
    {
        printf("%d->",temp->data);
        temp = temp->next;
    }
    printf("\n");
}

         片段循环完毕  temp!=head

5.  寻找节点

//查找节点
Plist find_node(Plist head ,int data)
{
    //空链表
    if(Empty_list(head))
        return NULL;
    
    Plist temp = head->next;
    while (temp != head)
    {
        if(temp->data == data)
            return temp;
        temp = temp->next;
    }
    return NULL;
}

6.  销毁链表

//销毁链表
void rm_list(Plist head)
{
    if(NULL == head)
        return;

    Plist temp , node;
    node = head->next;
    temp = node->next;

    while (temp != head)
    {
        temp = node->next;
        del_node(head ,node);
        free(node);
        node = temp;
    }
    free(head);
    head =NULL;

    printf("销毁成功\n");
}

        head指向NULL

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值