1. 程式人生 > >1、鏈表之增、刪、查實現(C語言)

1、鏈表之增、刪、查實現(C語言)

pan 沒有 null [] src ase 找到 調用 strlen

一、功能描述:

可以創建節點並添加到鏈表中、查看鏈表中的所有節點、並可以刪除特定的節點

二、代碼實現

1、主函數main主要實現的是從後臺鍵入不同的字符,執行對應的函數來實現特定的操作代碼如下:

int main(char argc, char *argv[])
{
    char c;
    while (1)
    {    
        c = getchar();                //鍵入一個字符
//        printf("c = %c\n",c);

        printf("Usage:\n");
        printf("<l> List all the notes\n
"); printf("<a> Add a node to chains\n"); printf("<d> Delete a node from chains\n"); printf("<q> quit\n"); printf("Enter the choise: \n"); switch (c) { case l : { list_all_notes(); //顯示鏈表中所有的節點
break; } case a : { add_a_node(); //鏈表中添加一個節點 break; } case d : { delete_a_node(); //刪除鏈表中的一個節點 break; }
case q : //退出死循環 { return 0; break; } defaut : { break; } } } return 0; }

2、add_a_node的主要作用創建一個節點,並初始化(節點分配內存、初始化節點name),最後調用add_note_to_chains函數把該節點添加到鏈表中,代碼如下:

 1 void add_a_node()
 2 {
 3     char *str;                //用來存放節點名字
 4     char name[128];        //臨時變量,鍵盤設置新節點的名字
 5     PT_Node ptNew;        //指針變量,指向新的節點
 6 
 7     printf("Please enter name of node to be added : ");
 8     scanf("%s", name);        //給新添加的節點取一個名字
 9 
10     str = malloc(strlen(name) + 1);    //為節點的名字分配空間
11     strcpy(str, name);
12 
13     ptNew = malloc(sizeof(T_Node));    //為新節點分配內存
14 
15     //初始化節點中的元素
16     ptNew ->name = str;            //節點中的name指向str
17     ptNew ->pre = NULL;            
18     ptNew ->next = NULL;
19 
20     add_note_to_chains(ptNew);    //把該節點添加到鏈表中
21 }

3、add_note_to_chains主要實現的是把節點掛載到鏈表中,代碼如下:

static void add_note_to_chains(PT_Node ptNew)
{
    PT_Node ptCur;
    if (g_ptNodeHead == NULL)
    {
        g_ptNodeHead = ptNew;//如果鏈表中沒有一個節點,則頭結點指向該節點
    }
    else
    {
        ptCur = g_ptNodeHead;
        while(ptCur ->next)    //遍歷找到當前節點的next元素為空
        {
            ptCur = ptCur ->next;    
        }
        
        ptCur->next = ptNew;    //把新的節點掛載到g_ptNodeHead鏈表中
        ptNew ->pre = ptCur;
        
    }
}

4、delete_a_node函數的主要功能是通過鍵入的name,索引到鏈表中對應的節點地址,最後調用delete_node函數刪除(卸載)鏈表中對應的節點,代碼如下:

static void delete_a_node()
{
    PT_Node ptFindName;
    char name[128];

    printf("Please enter the name of node to be deleted :");
    scanf("%s", name);

    ptFindName = get_name(name);    //通過名字獲得對應節點地址
    if (ptFindName == NULL)
    {
        printf("Don‘t have this node\n");
        return;
    }
        
    delete_node(ptFindName);        //刪除鏈表中對應的節點
}

5、get_name函數的作用是通過節點name在鏈表中索引到其對應的節點地址,代碼如下:

PT_Node get_name(char *name)
{
    PT_Node ptCar;
    if (g_ptNodeHead == NULL)
    {
        return NULL;
    }
    else
    {
        ptCar = g_ptNodeHead;
        do{
            if (strcmp (ptCar->name, name) == 0)
            {
                    printf("find \‘%s\‘ from chain\n",name);
                    return ptCar;
            }
            else
            {
                ptCar = ptCar->next;
            }
        }while (ptCar);

        printf("don‘t find \‘%s\‘ from chain\n",name);
        return NULL;
    }
}

6、delete_node函數的主要作用是卸載鏈表中對應的節點,卸載細節如下圖,其中ptCar為當前要被卸載的節點、ptPre為前一個節點、ptNext為後一個節點

技術分享圖片

對應代碼如下:

static void delete_node(PT_Node ptDel)
{
    PT_Node ptCar;
    PT_Node ptPre;
    PT_Node ptNext;
    if (g_ptNodeHead == ptDel)
    {
        g_ptNodeHead = ptDel->next;
//        return;
    }
    else{
        ptCar = g_ptNodeHead ->next;
//        printf("1111111111111\n");
        while(ptCar)
        {
            if (ptCar == ptDel)
            {
                //從鏈表中刪除
                ptPre    = ptCar ->pre;
                ptNext  = ptCar ->next;
                ptPre->next = ptNext;
//                printf("22222222\n");
                if(ptNext)
                {
                    ptNext ->pre = ptPre;
                }
                break;
            }
            else
            {
                ptCar = ptCar->next;
//                printf("333333\n");
            }
        }        
    }
    free(ptDel->name);    //釋放節點名字占用的內存
    free(ptDel);            //釋放節點占用的內存
}

7、list_all_notes顯示鏈表中的所用節點,代碼如下:

static void list_all_notes()
{
    PT_Node ptCar;
    ptCar = g_ptNodeHead;
    int i = 0;
    if (g_ptNodeHead == NULL)
    {
        printf("\n");
        printf("There is no node in chain list!\n");
        printf("\n");
    }
    while(ptCar)
    {
        printf("%02d : %s\n", i++, ptCar ->name);
        ptCar = ptCar ->next;
    }
}

8、完整代碼實現

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 
  5 //定義一個節點
  6 typedef struct T_NODE{
  7     char *name;
  8     struct T_NODE *pre;
  9     struct T_NODE *next;
 10 }T_Node, *PT_Node;
 11 
 12 static PT_Node g_ptNodeHead;    //鏈表頭
 13 
 14 static void add_note_to_chains(PT_Node ptNew)
 15 {
 16     PT_Node ptCur;
 17     if (g_ptNodeHead == NULL)
 18     {
 19         g_ptNodeHead = ptNew;//如果鏈表中沒有一個節點,則頭結點指向該節點
 20     }
 21     else
 22     {
 23         ptCur = g_ptNodeHead;
 24         while(ptCur ->next)    //遍歷找到當前節點的next元素為空
 25         {
 26             ptCur = ptCur ->next;    
 27         }
 28         
 29         ptCur->next = ptNew;    //把新的節點掛載到g_ptNodeHead鏈表中
 30         ptNew ->pre = ptCur;
 31         
 32     }
 33 }
 34 
 35 void add_a_node()
 36 {
 37     char *str;                //用來存放節點名字
 38     char name[128];        //臨時變量,鍵盤設置新節點的名字
 39     PT_Node ptNew;        //指針變量,指向新的節點
 40 
 41     printf("Please enter name of node to be added : ");
 42     scanf("%s", name);        //給新添加的節點取一個名字
 43 
 44     str = malloc(strlen(name) + 1);    //為節點的名字分配空間
 45     strcpy(str, name);
 46 
 47     ptNew = malloc(sizeof(T_Node));    //為新節點分配內存
 48 
 49     //初始化節點中的元素
 50     ptNew ->name = str;            //節點中的name指向str
 51     ptNew ->pre = NULL;            
 52     ptNew ->next = NULL;
 53 
 54     add_note_to_chains(ptNew);    //把該節點添加到鏈表中
 55 }
 56 
 57 
 58 PT_Node get_name(char *name)
 59 {
 60     PT_Node ptCar;
 61     if (g_ptNodeHead == NULL)
 62     {
 63         return NULL;
 64     }
 65     else
 66     {
 67         ptCar = g_ptNodeHead;
 68         do{
 69             if (strcmp (ptCar->name, name) == 0)
 70             {
 71                     printf("find \‘%s\‘ from chain\n",name);
 72                     return ptCar;
 73             }
 74             else
 75             {
 76                 ptCar = ptCar->next;
 77             }
 78         }while (ptCar);
 79 
 80         printf("don‘t find \‘%s\‘ from chain\n",name);
 81         return NULL;
 82 
 83     }
 84 
 85 }
 86 
 87 static void delete_node(PT_Node ptDel)
 88 {
 89     PT_Node ptCar;
 90     PT_Node ptPre;
 91     PT_Node ptNext;
 92     if (g_ptNodeHead == ptDel)
 93     {
 94         g_ptNodeHead = ptDel->next;
 95 //        return;
 96     }
 97     else{
 98         ptCar = g_ptNodeHead ->next;
 99 //        printf("1111111111111\n");
100         while(ptCar)
101         {
102             if (ptCar == ptDel)
103             {
104                 //從鏈表中刪除
105                 ptPre    = ptCar ->pre;
106                 ptNext  = ptCar ->next;
107                 ptPre->next = ptNext;
108 //                printf("22222222\n");
109                 if(ptNext)
110                 {
111                     ptNext ->pre = ptPre;
112                 }
113                 break;
114             }
115             else
116             {
117                 ptCar = ptCar->next;
118 //                printf("333333\n");
119             }
120         }        
121     }
122     free(ptDel->name);    //釋放節點名字占用的內存
123     free(ptDel);            //釋放節點占用的內存
124 }
125 
126 static void delete_a_node()
127 {
128     PT_Node ptFindName;
129     char name[128];
130 
131     printf("Please enter the name of node to be deleted :");
132     scanf("%s", name);
133 
134     ptFindName = get_name(name);    //通過名字獲得對應節點地址
135     if (ptFindName == NULL)
136     {
137         printf("Don‘t have this node\n");
138         return;
139     }
140         
141     delete_node(ptFindName);        //刪除鏈表中對應的節點
142 }
143 
144 static void list_all_notes()
145 {
146     PT_Node ptCar;
147     ptCar = g_ptNodeHead;
148     int i = 0;
149     if (g_ptNodeHead == NULL)
150     {
151         printf("\n");
152         printf("There is no node in chain list!\n");
153         printf("\n");
154     }
155     while(ptCar)
156     {
157         printf("%02d : %s\n", i++, ptCar ->name);
158         ptCar = ptCar ->next;
159     }
160 }
161 
162 int main(char argc, char *argv[])
163 {
164     char c;
165     while (1)
166     {    
167         c = getchar();                    //鍵入一個字符
168 //        printf("c = %c\n",c);
169 
170         printf("Usage:\n");
171         printf("<l> List all the notes\n");
172         printf("<a> Add a node to chains\n");
173         printf("<d> Delete a node from chains\n");
174         printf("<q> quit\n");
175         printf("Enter the choise: \n");
176         switch (c)
177         {
178             case l :
179             {
180                 list_all_notes();        //顯示鏈表中所有的節點
181                 break;
182             }
183             case a :
184             {
185                 add_a_node();        //鏈表中添加一個節點
186                 break;
187             }            
188             case d :
189             {
190                 delete_a_node();        //刪除鏈表中的一個節點
191                 break;
192             }
193             case q :                    //退出死循環
194             {
195                 return 0;
196                 break;
197             }
198             defaut :
199             {        
200 
201                 break;
202             }            
203         }
204     }
205     return 0;
206 }

1、鏈表之增、刪、查實現(C語言)