单链表

链表是一种常见的数据结构,与数组在表现形式上很相似,其无空间限制,可以存放很多数据,同样避免了空间浪费,这些都是数组所没有的优点,但也有一个最大的缺点,就是不便于数据访问。链表操作包括数据插入、数据删除、头插、头删、尾插、尾删、销毁等。接下来就用图解的方式来届时链表的操作:

链表形式:
在这里插入图片描述
链表有很多节点形象的依次连接在一起,每个节点都由一个数据域和指针域构成,指针域存放着下一个节点的地址,故而形象的使各个节点依次相连。链表尾的指针域要置空,以免会出现不必要的差错,同样也便于链表遍历。

插入一个节点:
在这里插入图片描述
1节点的指针域原本指向的是2节点,在1节点处插入一个节点,原来的2节点变为了3节点,插入的节点变为了2节点,1节点的指针域原本存放着3(原2节点)节点的地址,现在重新赋值,变成存放着2(新插入的节点)节点的地址,而2(新插入的节点)节点的指针域存放着3(原2节点)节点的地址。

删除一个节点
在这里插入图片描述
例如删除2节点,只需将原3(现2节点)节点的地址赋给1节点的指针域中,再将原2(即删除的节点)节点的指针域释放掉即可

头插:
在这里插入图片描述
1节点原本是之前的0节点,也就是链表头,现在插入一个链表头进来,原链表头就变为了1节点,新插入的节点就变成了链表头,此操作只需把1(原链表头)节点的地址赋给0(现链表头)节点。

头删:

头删的操作更为简单,直接把链表头释放掉即可,再将原来的1节点在设置为链表头即可,再次就不画图了。

具体代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

 
typedef struct ListNode
{
    int data;
    struct ListNode* next;
}ListNode;

typedef struct List
{
    ListNode* head;
}List;

ListNode* ListInit()                             //开辟一个空间
{
    return  malloc(sizeof(ListNode));
}

 

void insert_list(ListNode* head, int n, int data)    //插入一个节点
{
    ListNode* tem;
    for (tem = head;tem&&n--; tem = tem->next);//找到要插入数据的位置
    ListNode* new_data =ListInit();
    new_data->data =data;
    new_data->next =tem->next;//tem->next中存放的是下一个数据的地址,将这个地址赋给
    
new_data的指针域

    tem->next =new_data;//使tem->next指向new_data
}

void print(ListNode* head)                   //打印
{
    ListNode* tem;
    if (head == NULL)
    {
        printf("\n该链表不存在\n");
        return;
    }
    for (tem = head; tem;tem = tem->next)
    {
        printf("%d  ", tem->data);
    }
    printf("\n");
}

 void  del_list(ListNode*head, int n)       //删除
{
    ListNode* tem;
    for (tem = head;tem&&n--; tem = tem->next);//找到要删除这个数据的上一个数据的位置
    struct list *tmp =tem->next;//将这个要删除的数据赋给tmp
    tem->next =tem->next->next;//将这个要删除的数据的next中存放的地址赋给该数据的上一个位置
    free(tmp);
}

 void   insert_front(ListNode** head, int data) 
//头插法
{
    ListNode* tem =ListInit();
    tem->data = data;//赋值数据
    tem->next =*head;//在tem的指针域中存放之前的链表头
    *head = tem;//使tem成为新的链表头
} 

void   del_front(ListNode** head)     //头删
{
    ListNode* tmp =(*head)->next;//将链表头的指针域中存放的下一个节点的地址赋给tmp
    free(*head);//释放链表头
    *head = tmp;//使tmp成为新的链表头
} 

void   insert_after(ListNode* head, int data)  //尾插
{
    ListNode* tem;
    int n = 0;
    for (tem = head; tem;tem = tem->next)
    {
        n++;
    }
    insert_list(head, n -1, data);
}
void  del_after(ListNode  *head)    //尾删
{
    ListNode* tem;
    int n = 0, b;
    for (tem = head; tem;tem = tem->next)
    {
        n++;
    }
    b = n - 2;
    for (tem = head;tem&&b--; tem = tem->next);
    free(tem->next->next);
    tem->next = NULL;
}

void  destory(ListNode  *head)    //销毁链表
{
    ListNode* tem;
    int n = 0, b;
    for (tem = head; tem;tem = tem->next)//链表遍历
    {
        n++;//统计节点数
    }
    b = n - 1;
    while ((head->next)&& b--)
    {
        del_list(head,b);//依次删除链表头
    }
    free(head);//释放最后一个链表头
} 

int   main()
{
    ListNode* first =ListInit();
    first->next = NULL;
    first->data = 1;
    
    insert_list(first, 0,7);

   insert_list(first, 0,4);
    insert_list(first, 2,4);
    insert_list(first, 2,13);
    insert_list(first, 3,11);
    insert_front(&first,9);
    insert_list(first, 6,0);
    //del_front(&first);
    //del_list(first, 0);
    insert_after(first,6);
   del_after(first);
    del_front(&first);
    print(first);
    del_front(&first);
    print(first);
    destory(first);
    first = NULL;
    print(first);
    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值