链表的基本操作


  在说链表之前,我们先说说顺序存储。其中我们最熟悉的一种顺序存储的数据结构就是数组,当我们想要给数组中插入一个元素时,为保证顺序以及其他元素不丢失,我们需要在插入元素后,将后面的元素整体后移。所以容易看出这样有着这两个弊端:第一:我们所需要移动的元素有很多时,会浪费算力。第二:我们必须为数组开足够多的空间,否则会存在溢出风险。
为了避免这两个弊端,我们引入链式存储——链表。
什么是链表?
简单来说,链表的利用结构体,额外开辟出一份内存空间去作指针,它总是指向下一个结点,一个个结点通过指针相互串联,这就形成了我们的链表。

 

 其中DATA数据元素(数据域),可以是int类型或char类型,甚至可以是结构体。NEXT为一个指针通常是用来指向下一个结点,链表的尾部NEXT指向NULL,因为它没有可以指向的空间了。

 

 

 对于一个单链表的结点定义:

 

 

``

 1 //定义结点类型 
 2 typedef struct Node
 3 {
 4     int DATA;//数据域 
 5     struct Node* NEXT;//指针域 
 6 }Node,* pointnode;//Node表示结点的类型,pointnode表示指向Node结点类型的指针类型
 7 ```
 8 1.对链表进行初始化:
 9 
10 ```c
11 pointnode Initialize()
12 {
13     Node* H=(Node*)malloc(sizeof(Node));  //开辟空间
14     if(H==NULL)    //判断是否开辟成功 
15     {
16         printf("开辟失败!");//开辟失败的提示 
17         exit(0);             //    开辟失败结束程序(根据情况看是否添加) 
18      } 
19      H->NEXT=NULL;            //指针指向NULL 
20  } 
21 ```
22 2.创建单链表:
23 <1>头插法
24     从一个空表开始,生成新结点,并将数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头即头结点之后。
25 ```c
26 pointnode listofhead()
27 {
28     Node* H = (Node*)malloc(sizeof(Node));//开辟一个头空间
29     H -> NEXT= NULL;                        //初始化为空
30 
31     int x;
32     while (scanf("%d", &x) != EOF)        //输入数据,当输入空的时候停止(在Windows下:Ctrl+Z)
33     {
34         Node* p = (Node*)malloc(sizeof(Node));
35         p->DATA = x;                //赋值给数据域
36         p->NEXT = H->NEXT;            //将节点插到表头
37         H->NEXT = p;
38     }
39     return H;
40 }
41 ```
42 <2>尾插法
43     将新结点逐个插入到当前链表的表尾上,增加一个尾指针, 使其始终指向当前链表的尾结点。
44 ```c
45 pointnode listofend()
46 {
47     Node* H = (Node*)malloc(sizeof(Node));    //开辟头空间
48     H->NEXT = NULL;            //初始化
49 
50     int x;
51     Node* l;        //定义为尾指针
52     l = H;          // 尾指针开始指向头,始终指向尾。
53     while (scanf("%d", &x) != EOF)
54     {
55         Node* p = (Node*)malloc(sizeof(Node));
56         p->DATA = x;
57         l->NEXT = p;    //将结点插到表头
58         l = p;
59 
60     }
61     l->NEXT = NULL;
62     return H;
63 }
64 ```
65 注意:头插法的顺序是逆序的:表头->[n]->···->[2]->[1]->NULL
66            尾插法是正序的:表头->[1]->[2]->····[n]->NULL
67 3.链表的遍历
68 
69 ```c
70 void listoftravel(pointnode H)
71 {
72     Node* p = H->NEXT;
73 
74     int i = 1;
75     while (p)
76     {
77         printf("第%d个数据是%d\n", i++, p->DATA);
78         p = p->NEXT;
79     }
80 
81 }

 2.链表的插入

 

 

 

 

 1 //链表的插入
 2 pointnode datainlist(pointnode H,int i,int x)
 3 {
 4     Node* preve = H;
 5     int seek;
 6     for (seek = 1; seek < i; seek++)//寻找元素位置
 7     {
 8         preve = preve->NEXT;
 9     }
10     Node* p = (Node*)malloc(sizeof(Node));
11     p->DATA = x;
12     p->NEXT = preve->NEXT;
13     preve->NEXT = p;
14     return H;
15 }

3.链表修改

//链表的修改
pointnode moddata(pointnode H,int x,int t)
{
Node* p = H->NEXT;

while (p)
{
if (p->DATA == x)
{
p->DATA = t;
}
p = p->NEXT;
}
return H;
}

4.链表删除

//链表的删除
pointnode  freedata(pointnode H,int x)
{
    Node* p;
    Node* preve;//前驱结点
    p = H->NEXT;

    while (p->DATA != x)//查找元素
    {
        preve = p;
        p = p ->NEXT;
    }
    preve->NEXT = p->NEXT;
    free(p);    //删除操作
    return H;

}

5.完整代码

#include<stdio.h>
#include<stdlib.h>
//定义结点类型 
typedef struct Node
{
    int DATA;//数据域 
    struct Node* NEXT;//指针域 
}Node, * pointnode;
//Node表示结点的类型,pointnode表示指向Node结点类型的指针类型

//链表的初始化 
pointnode Initialize()
{
    Node* H = (Node*)malloc(sizeof(Node));  //开辟空间
    if (H == NULL)    //判断是否开辟成功 
    {
        printf("开辟失败!");//开辟失败的提示 
        exit(0);             //    开辟失败结束程序(根据情况看是否添加) 
    }
    H->NEXT = NULL;            //指针指向NULL 
}
//头插法建立链表
pointnode listofhead()
{
    Node* H = (Node*)malloc(sizeof(Node));//开辟一个头空间
    H = NULL;                        //初始化为空

    int x;
    while (scanf("%d", &x) != EOF)        //输入数据,当输入空的时候停止(在Windows下:Ctrl+Z)
    {
        Node* p = (Node*)malloc(sizeof(Node));
        p->DATA = x;                //赋值给数据域
        p->NEXT = H->NEXT;            //将节点插到表头
        H->NEXT = p;
    }
    return H;
}

//尾插法
pointnode listofend()
{
    Node* H = (Node*)malloc(sizeof(Node));    //开辟头空间
    H->NEXT = NULL;            //初始化

    int x;
    Node* l;        //定义为尾指针
    l = H;          // 尾指针开始指向头,始终指向尾。
    while (scanf("%d", &x) != EOF)
    {
        Node* p = (Node*)malloc(sizeof(Node));
        p->DATA = x;
        l->NEXT = p;    //将结点插到表头
        l = p;

    }
    l->NEXT = NULL;
    return H;
}
//遍历链表
void listoftravel(pointnode H)
{
    Node* p = H->NEXT;

    int i = 1;
    while (p)
    {
        printf("第%d个数据是%d\n", i++, p->DATA);
        p = p->NEXT;
    }

}
//链表的插入
pointnode datainlist(pointnode H,int i,int x)
{
    Node* preve = H;
    int seek;
    for (seek = 1; seek < i; seek++)//寻找元素位置
    {
        preve = preve->NEXT;
    }
    Node* p = (Node*)malloc(sizeof(Node));
    p->DATA = x;
    p->NEXT = preve->NEXT;
    preve->NEXT = p;
    return H;
}
//链表的修改
pointnode moddata(pointnode H,int x,int t)
{
    Node* p = H->NEXT;

    while (p)
    {
        if (p->DATA == x)
        {
            p->DATA = t;
        }
        p = p->NEXT;
    }
    return H;
}

//链表的删除
pointnode  freedata(pointnode H,int x)
{
    Node* p;
    Node* preve;//前驱结点
    p = H->NEXT;

    while (p->DATA != x)//查找元素
    {
        preve = p;
        p = p ->NEXT;
    }
    preve->NEXT = p->NEXT;
    free(p);    //删除操作
    return H;

}
int main()
{
    pointnode list;
    Initialize();
    list = listofend();
    //list = listofhead();
    listoftravel(list);

    //链表的修改
    int x;
    int t;
    printf("你想修改的数据是:");
    scanf("%d", &x);
    printf("你想把他改为:");
    scanf("%d", &t);
    moddata(list, x, t);
    listoftravel(list);

    //链表的插入
    int i;
    printf("你想在哪个位置插入数据:");
    scanf("%d", &i);
    printf("你想插入的数据是:");
    scanf("%d", &x);
    datainlist(list, i, x);
    listoftravel(list);

    //链表的删除
    printf("你想删除的数据是:");
    scanf("%d", &x);
    freedata(list, x);
    listoftravel(list);
    return 0;
}
完整操作

希望大家也可以关注本人的CSDN,内容都是一致的!如有错误,请指正!!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM