鏈表的基本操作


  在說鏈表之前,我們先說說順序存儲。其中我們最熟悉的一種順序存儲的數據結構就是數組,當我們想要給數組中插入一個元素時,為保證順序以及其他元素不丟失,我們需要在插入元素后,將后面的元素整體后移。所以容易看出這樣有着這兩個弊端:第一:我們所需要移動的元素有很多時,會浪費算力。第二:我們必須為數組開足夠多的空間,否則會存在溢出風險。
為了避免這兩個弊端,我們引入鏈式存儲——鏈表。
什么是鏈表?
簡單來說,鏈表的利用結構體,額外開辟出一份內存空間去作指針,它總是指向下一個結點,一個個結點通過指針相互串聯,這就形成了我們的鏈表。

 

 其中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