天天看點

c語言提高學習筆記——03-c提高08day_資料結構

在學習c語言提高-資料結構總結了筆記,并分享出來。有問題請及時聯系部落客:​​Alliswell_WP​​,轉載請注明出處。

03-c提高08day_資料結構

目錄:

1、資料結構理論

(1)資料結構概念

(2)算法的概念

2、線性表

(1)線性表基本概念

(2)線性表的順序存儲

練習1:

動态數組(+初始化、+插入、+周遊)

動态數組(+删除、+銷毀)

動态數組(分檔案實作)

練習2:

單向連結清單(版本一)——(+初始化、+插入、+周遊)

單向連結清單(版本一)——(+值删除、+位置删除、+大小、+清空、+銷毀)

 練習3:

單向連結清單(版本二)

1、資料結構理論

(1)資料結構概念

資料結構是計算機存儲、組織資料的方式。資料結構是指互相之間存在一種或多種特定關系的資料元素的集合,通常情況下,精心選擇的資料結構可以帶來更高的運作或者存儲效率。資料結構往往同高效的檢索算法和索引技術有關。

資料結構是計算機存儲、組織資料的方式。

(2)算法的概念

算法是特定問題求解步驟的描述,在計算機中表現為指令的有限序列,算法是獨立存在的一種解決問題的方法和思想。

對于算法而言,語言并不重要,重要的是思想。

2、線性表

(1)線性表基本概念

線性結構是一種最簡單且常用的資料結構。線性結構的基本特點是節點之間滿足線性關系。本章讨論的動态數組、連結清單、棧、隊列都屈于線性結構。他們的共同之處,是節點中有且隻有一個開始節點和終端節點。按這種關系,可以把它們的所有節點排列成一個線性序列。但是,他們分别屈于幾種不同的抽象資料類型實作,它們之間的差別,主要就是操作的不同。

線性表是零個或者多個資料元素的有限序列,資料元素之問是有順序的,資料元素個數是有限的,資料元素的類型必須相同。

(2)線性表的順序存儲

通常線性表可以采用順序存儲和鍊式存儲。這節課我們主要探讨順序存儲結構以及對應的運算算法的實作。

采用順序存儲是表示線性表最簡單的方法,具體做法是:将線性表中的元素一個接一個的存儲在一塊連續的存儲區域中,這種順序表示的線性表也稱為順序表。

練習1:

動态數組(+初始化、+插入、+周遊)

1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 
  6 1.先把所需要的資料資訊結構定義下來
  7 struct DynamicArray
  8 {
  9     //數組存儲元素的空間的首位址
 10     void** addr;
 11     //存儲資料的記憶體中最大能夠容納多少元素
 12     int capacity;//容量
 13     //目前存儲資料的記憶體中有多少個元素
 14     int size;//大小
 15 };
 16 
 17 //初始化數組
 18 struct DynamicArray* Init_DynamicArray(int capacity)
 19 {
 20     if(capacity <= 0)
 21     {
 22         return NULL;
 23     }
 24     struct DynamicArray* arr = malloc(sizeof(struct DynamicArray));
 25     if(NULL == arr)
 26     {
 27         return NULL;
 28     }
 29     arr->capacity = capacity;
 30     arr->addr = malloc(sizeof(void*) * arr->capacity);
 31     arr->size = 0;
 32     
 33     return arr;
 34 }
 35 //插入元素
 36 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data)
 37 {
 38     if(NULL == arr)
 39     {
 40         return;
 41     }
 42     if(NULL == data)
 43     {
 44         return;
 45     }
 46     if(pos < 0 || pos > arr->size)//檢查插入位置的合法性
 47     {
 48         pos = arr->size;
 49     }
 50     if(arr->size >= arr->capacity)
 51     {
 52         //1.申請一塊更大的記憶體空間
 53         int newcapacity = arr->capacity * 2;
 54         void** newspace = malloc(sizeof(void*) * newcapacity);
 55         
 56         //2.将原來空間的資料拷貝到新空間
 57         memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity);
 58         
 59         //3.釋放原來空間的記憶體
 60         free(arr->addr);
 61         
 62         //4.更新addr指向
 63         arr->addr = newspace;
 64         arr->capacity = newcapacity;
 65     }
 66     
 67     //移動元素,給pos位置空出位置來
 68     for(int i = arr->size - 1; i >= pos; --i)
 69     {
 70         arr->addr[i + 1] = addr->addr[i];
 71     }
 72     
 73     //将新元素插入到pos位置
 74     arr->addr[pos] = data;
 75     arr->size++;
 76 }
 77 //周遊
 78 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*))
 79 {
 80     if(NULL == arr)
 81     {
 82         return;
 83     }
 84     if(NULL == _callback)
 85     {
 86         return;
 87     }
 88     for(int i = 0; i < arr->size; ++i)
 89     {
 90         _callback(arr->addr[i]);
 91     }
 92 }
 93 
 94 //初始化數組
 95 struct DynamicArray* Init_DynamicArray(int capacity);
 96 //插入元素
 97 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data);
 98 //周遊
 99 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*));
100 
101 
102 struct Person
103 {
104     char name[64];
105     int age;
106 };
107 
108 void myPrint(void* data)
109 {
110     struct Person* person = (struct Person*)data;
111     printf("Name:%s Age:%d\n", person->name, person->age);
112 }
113 
114 void test()
115 {
116     //建立動态數組
117     struct DynamicArray* da = Init_DynamicArray(5);
118     //動态數組添加元素
119     struct Person p1 = {"aaa", 10};
120     struct Person p2 = {"bbb", 20};
121     struct Person p3 = {"ccc", 30};
122     struct Person p4 = {"ddd", 40};
123     struct Person p5 = {"eee", 50};
124     struct Person p6 = {"fff", 60};
125     
126     Insert_DynamicArray(da, 100, &p1);
127     Insert_DynamicArray(da, 100, &p2);
128     Insert_DynamicArray(da, 100, &p3);
129     Insert_DynamicArray(da, 100, &p4);
130     Insert_DynamicArray(da, 100, &p5);
131     
132     printf("capacity:%d\n", da->capacity);//列印容量
133     Insert_DynamicArray(da, 100, &p6);//超出空間容量,擴大一倍
134     printf("capacity:%d\n", da->capacity);//列印容量
135     
136     Foreach_DynamicArray(data, myPrint);
137 }
138 
139 int main(){
140 
141     test();
142     
143     system("pause");
144     return EXIT_SUCCESS;
145 }      

 動态數組(+删除、+銷毀)

1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<stdio.h>
  3 #include<string.h>
  4 #include<stdlib.h>
  5 
  6 1.先把所需要的資料資訊結構定義下來
  7 struct DynamicArray
  8 {
  9     //數組存儲元素的空間的首位址
 10     void** addr;
 11     //存儲資料的記憶體中最大能夠容納多少元素
 12     int capacity;//容量
 13     //目前存儲資料的記憶體中有多少個元素
 14     int size;//大小
 15 };
 16 
 17 //初始化數組
 18 struct DynamicArray* Init_DynamicArray(int capacity)
 19 {
 20     if(capacity <= 0)
 21     {
 22         return NULL;
 23     }
 24     struct DynamicArray* arr = malloc(sizeof(struct DynamicArray));
 25     if(NULL == arr)
 26     {
 27         return NULL;
 28     }
 29     arr->capacity = capacity;
 30     arr->addr = malloc(sizeof(void*) * arr->capacity);
 31     arr->size = 0;
 32     
 33     return arr;
 34 }
 35 //插入元素
 36 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data)
 37 {
 38     if(NULL == arr)
 39     {
 40         return;
 41     }
 42     if(NULL == data)
 43     {
 44         return;
 45     }
 46     if(pos < 0 || pos > arr->size)//檢查插入位置的合法性
 47     {
 48         pos = arr->size;
 49     }
 50     
 51     //判斷空間是否足夠
 52     if(arr->size >= arr->capacity)
 53     {
 54         //1.申請一塊更大的記憶體空間
 55         int newcapacity = arr->capacity * 2;
 56         void** newspace = malloc(sizeof(void*) * newcapacity);
 57         
 58         //2.将原來空間的資料拷貝到新空間
 59         memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity);
 60         
 61         //3.釋放原來空間的記憶體
 62         free(arr->addr);
 63         
 64         //4.更新addr指向
 65         arr->addr = newspace;
 66         arr->capacity = newcapacity;
 67     }
 68     
 69     //移動元素,給pos位置空出位置來
 70     for(int i = arr->size - 1; i >= pos; --i)
 71     {
 72         arr->addr[i + 1] = addr->addr[i];
 73     }
 74     
 75     //将新元素插入到pos位置
 76     arr->addr[pos] = data;
 77     arr->size++;
 78 }
 79 //周遊
 80 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*))
 81 {
 82     if(NULL == arr)
 83     {
 84         return;
 85     }
 86     if(NULL == _callback)
 87     {
 88         return;
 89     }
 90     for(int i = 0; i < arr->size; ++i)
 91     {
 92         _callback(arr->addr[i]);
 93     }
 94 }
 95 
 96 //位置删除
 97 void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos)
 98 {
 99     if(NULL == arr)
100     {
101         return;
102     }
103     if(pos < 0 || pos > arr->size - 1)
104     {
105         return;
106     }
107     
108     for(int i = pos; i < arr->size -1; ++i)
109     {
110         arr->addr[i] = arr->addr[i + 1];
111     }
112     arr->size--;
113 }
114 
115 //按值删除
116 void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*))
117 {
118     if(NULL == arr)
119     {
120         return;
121     }
122     if(NULL == data)
123     {
124         return;
125     }
126     if(NULL == compare)
127     {
128         return;
129     }
130     
131     for(int i = 0; i < arr->size; ++i)
132     {
133         if(compare(arr->addr[i], data))
134         {
135             RemoveByPos_DynamicArray(arr, i);
136             break;
137         }
138     }
139     
140 }
141 
142 //銷毀數組
143 void Destroy_DynamicArray(struct DynamicArray* arr)
144 {
145     if(NULL == arr)
146     {
147         return;
148     }    
149     if(arr->addr != arr)
150     {
151         free(arr->addr);
152         arr->addr = NULL;
153     }
154     free(arr);
155     arr = NULL;            
156 }
157 
158 //初始化數組
159 struct DynamicArray* Init_DynamicArray(int capacity);
160 //插入元素
161 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data);
162 //周遊
163 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*));
164 
165 
166 struct Person
167 {
168     char name[64];
169     int age;
170 };
171 
172 void myPrint(void* data)
173 {
174     struct Person* person = (struct Person*)data;
175     printf("Name:%s Age:%d\n", person->name, person->age);
176 }
177 
178 int myCompare(void* d1, void* d2)
179 {
180     struct person* p1 = (struct Person*)d1;
181     struct person* p2 = (struct Person*)d2;
182     
183     return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
184 }
185 
186 
187 void test()
188 {
189     //建立動态數組
190     struct DynamicArray* da = Init_DynamicArray(5);
191     //動态數組添加元素
192     struct Person p1 = {"aaa", 10};
193     struct Person p2 = {"bbb", 20};
194     struct Person p3 = {"ccc", 30};
195     struct Person p4 = {"ddd", 40};
196     struct Person p5 = {"eee", 50};
197     struct Person p6 = {"fff", 60};
198     
199     Insert_DynamicArray(da, 0, &p1);
200     Insert_DynamicArray(da, 0, &p2);
201     Insert_DynamicArray(da, 0, &p3);
202     Insert_DynamicArray(da, 1, &p4);
203     Insert_DynamicArray(da, 1, &p5);
204     
205     printf("capacity:%d\n", da->capacity);//列印容量
206     Insert_DynamicArray(da, 100, &p6);//超出空間容量,擴大一倍3 5 4 2 1 6
207     printf("capacity:%d\n", da->capacity);//列印容量
208     
209     Foreach_DynamicArray(data, myPrint);
210     
211     printf("-----------------\n");
212     RemoveByPos_DynamicArray(data, 2);//3 5 2 1 6
213     Foreach_DynamicArray(data, myPrint);
214     
215     printf("-----------------\n");
216     struct Person pDel = {"aaa", 10};
217     RemoveByValue(da, &pDel, myCompare);
218     Foreach_DynamicArray(data, myPrint);
219     
220     //銷毀
221     Destroy_DynamicArray(da);
222 }
223 
224 int main(){
225 
226     test();
227     
228     system("pause");
229     return EXIT_SUCCESS;
230 }      

動态數組(分檔案實作)

動态數組.c

1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<stdlib.h>
 5 #inlcude"DynamicArray.h"
 6 
 7 
 8 struct Person
 9 {
10     char name[64];
11     int age;
12 };
13 
14 void myPrint(void* data)
15 {
16     struct Person* person = (struct Person*)data;
17     printf("Name:%s Age:%d\n", person->name, person->age);
18 }
19 
20 int myCompare(void* d1, void* d2)
21 {
22     struct person* p1 = (struct Person*)d1;
23     struct person* p2 = (struct Person*)d2;
24     
25     return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
26 }
27 
28 
29 void test()
30 {
31     //建立動态數組
32     struct DynamicArray* da = Init_DynamicArray(5);
33     //動态數組添加元素
34     struct Person p1 = {"aaa", 10};
35     struct Person p2 = {"bbb", 20};
36     struct Person p3 = {"ccc", 30};
37     struct Person p4 = {"ddd", 40};
38     struct Person p5 = {"eee", 50};
39     struct Person p6 = {"fff", 60};
40     
41     Insert_DynamicArray(da, 0, &p1);
42     Insert_DynamicArray(da, 0, &p2);
43     Insert_DynamicArray(da, 0, &p3);
44     Insert_DynamicArray(da, 1, &p4);
45     Insert_DynamicArray(da, 1, &p5);
46     
47     printf("capacity:%d\n", da->capacity);//列印容量
48     Insert_DynamicArray(da, 100, &p6);//超出空間容量,擴大一倍3 5 4 2 1 6
49     printf("capacity:%d\n", da->capacity);//列印容量
50     
51     Foreach_DynamicArray(data, myPrint);
52     
53     printf("-----------------\n");
54     RemoveByPos_DynamicArray(data, 2);//3 5 2 1 6
55     Foreach_DynamicArray(data, myPrint);
56     
57     printf("-----------------\n");
58     struct Person pDel = {"aaa", 10};
59     RemoveByValue(da, &pDel, myCompare);
60     Foreach_DynamicArray(data, myPrint);
61     
62     //銷毀
63     Destroy_DynamicArray(da);
64 }
65 
66 int main(){
67 
68     test();
69     
70     system("pause");
71     return EXIT_SUCCESS;
72 }      

DynamicArray.h

1 #pragma once
 2 
 3 #include<stdlib.h>
 4 #include<stdio.h>
 5 #include<string.h>
 6 
 7 #ifdef __cplusplus
 8 extern "C"{
 9 
10     1.先把所需要的資料資訊結構定義下來
11     struct DynamicArray
12     {
13         //數組存儲元素的空間的首位址
14         void** addr;
15         //存儲資料的記憶體中最大能夠容納多少元素
16         int capacity;//容量
17         //目前存儲資料的記憶體中有多少個元素
18         int size;//大小
19     };
20 
21     //初始化數組
22     struct DynamicArray* Init_DynamicArray(int capacity);
23     //插入元素
24     void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data);
25     //周遊
26     void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*));
27     //位置删除
28     void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos);
29     //按值删除
30     void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*));
31     //銷毀數組
32     void Destroy_DynamicArray(struct DynamicArray* arr);
33 
34 #ifdef __cplusplus
35 }
36 #endif      

DynamicArray.c

1 #inlcude"DynamicArray.h"
  2 
  3 1.先把所需要的資料資訊結構定義下來
  4 struct DynamicArray
  5 {
  6     //數組存儲元素的空間的首位址
  7     void** addr;
  8     //存儲資料的記憶體中最大能夠容納多少元素
  9     int capacity;//容量
 10     //目前存儲資料的記憶體中有多少個元素
 11     int size;//大小
 12 };
 13 
 14 //初始化數組
 15 struct DynamicArray* Init_DynamicArray(int capacity)
 16 {
 17     if(capacity <= 0)
 18     {
 19         return NULL;
 20     }
 21     struct DynamicArray* arr = malloc(sizeof(struct DynamicArray));
 22     if(NULL == arr)
 23     {
 24         return NULL;
 25     }
 26     arr->capacity = capacity;
 27     arr->addr = malloc(sizeof(void*) * arr->capacity);
 28     arr->size = 0;
 29     
 30     return arr;
 31 }
 32 //插入元素
 33 void Insert_DynamicArray(struct DynamicArray* arr, int pos, void* data)
 34 {
 35     if(NULL == arr)
 36     {
 37         return;
 38     }
 39     if(NULL == data)
 40     {
 41         return;
 42     }
 43     if(pos < 0 || pos > arr->size)//檢查插入位置的合法性
 44     {
 45         pos = arr->size;
 46     }
 47     
 48     //判斷空間是否足夠
 49     if(arr->size >= arr->capacity)
 50     {
 51         //1.申請一塊更大的記憶體空間
 52         int newcapacity = arr->capacity * 2;
 53         void** newspace = malloc(sizeof(void*) * newcapacity);
 54         
 55         //2.将原來空間的資料拷貝到新空間
 56         memcpy(newspace, arr->addr, sizeof(void*) * arr->capacity);
 57         
 58         //3.釋放原來空間的記憶體
 59         free(arr->addr);
 60         
 61         //4.更新addr指向
 62         arr->addr = newspace;
 63         arr->capacity = newcapacity;
 64     }
 65     
 66     //移動元素,給pos位置空出位置來
 67     for(int i = arr->size - 1; i >= pos; --i)
 68     {
 69         arr->addr[i + 1] = addr->addr[i];
 70     }
 71     
 72     //将新元素插入到pos位置
 73     arr->addr[pos] = data;
 74     arr->size++;
 75 }
 76 //周遊
 77 void Foreach_DynamicArray(struct DynamicArray* arr, void(*_callback)(void*))
 78 {
 79     if(NULL == arr)
 80     {
 81         return;
 82     }
 83     if(NULL == _callback)
 84     {
 85         return;
 86     }
 87     for(int i = 0; i < arr->size; ++i)
 88     {
 89         _callback(arr->addr[i]);
 90     }
 91 }
 92 
 93 //位置删除
 94 void RemoveByPos_DynamicArray(struct DynamicArray* arr, int pos)
 95 {
 96     if(NULL == arr)
 97     {
 98         return;
 99     }
100     if(pos < 0 || pos > arr->size - 1)
101     {
102         return;
103     }
104     
105     for(int i = pos; i < arr->size -1; ++i)
106     {
107         arr->addr[i] = arr->addr[i + 1];
108     }
109     arr->size--;
110 }
111 
112 //按值删除
113 void RemoveByValue(struct DynamicArray* arr, void* data, int(*compare)(void*, void*))
114 {
115     if(NULL == arr)
116     {
117         return;
118     }
119     if(NULL == data)
120     {
121         return;
122     }
123     if(NULL == compare)
124     {
125         return;
126     }
127     
128     for(int i = 0; i < arr->size; ++i)
129     {
130         if(compare(arr->addr[i], data))
131         {
132             RemoveByPos_DynamicArray(arr, i);
133             break;
134         }
135     }
136     
137 }
138 
139 //銷毀數組
140 void Destroy_DynamicArray(struct DynamicArray* arr)
141 {
142     if(NULL == arr)
143     {
144         return;
145     }    
146     if(arr->addr != arr)
147     {
148         free(arr->addr);
149         arr->addr = NULL;
150     }
151     free(arr);
152     arr = NULL;            
153 }      

練習2:單向連結清單(版本一)——(+初始化、+插入、+周遊)

記憶體模型圖如下:

c語言提高學習筆記——03-c提高08day_資料結構

單向連結清單(版本一).c

1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<stdlib.h>
 5 #include"LinkList.h"
 6 
 7 struct Person
 8 {
 9     char name[64];
10     int age;
11 };
12 
13 void myPrint(void* data)
14 {
15     struct Person* person = (struct Person*)data;
16     printf("Name:%s Age:%d\n", person->name, person->age);
17 }
18 
19 void test()
20 {
21     //建立連結清單
22     LinkList list = Init_LinkList();
23     
24     //建立資料
25     struct Person p1 = {"aaa", 10};
26     struct Person p2 = {"bbb", 20};
27     struct Person p3 = {"ccc", 30};
28     struct Person p4 = {"ddd", 40};
29     struct Person p5 = {"eee", 50};
30     struct Person p6 = {"fff", 60};
31     struct Person p7 = {"ggg", 70};
32     
33     //插入資料
34     Insert_LinkList(list, 0, &p1);
35     Insert_LinkList(list, 0, &p2);
36     Insert_LinkList(list, 1, &p3);//2 3 1
37     Insert_LinkList(list, 2, &p4);//2 3 4 1
38     Insert_LinkList(list, 20, &p5);//2 3 4 1 5
39     Insert_LinkList(list, 3, &p6);//2 3 6 4 1 5
40     Insert_LinkList(list, 6, &p7);//2 3 6 4 1 7 5
41     
42     Foreach_LinkList(list, myPrint);
43 }
44     
45 int main(){
46 
47     test();
48     
49     system("pause");
50     return EXIT_SUCCESS;
51 }      

LinkList.h

1 #pragma once
 2 
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<stdio.h>
 6 
 7 #ifdef __cpluscplus
 8 extern "C"{
 9 #endif
10 
11 
12     
13     typedef void* LinkList;
14     typedef void(*FOREACH)(void*);
15     
16     //初始化連結清單
17     LinkList Init_LinkList();
18     //插入結點
19     void Insert_LinkList(LinkList list, int pos, void* data);
20     //周遊連結清單
21     void Foreach_LinkList(LinkList list, FOREACH myforeach);
22 
23 
24 #ifdef __cpluscplus
25 }
26 #endif      

LinkList.c

1 #include"LinkList.h"
 2 
 3 //連結清單結點資料類型
 4 struct LinkNode
 5 {
 6     void* data;
 7     struct LinkNode* next;
 8 };
 9 
10 //連結清單資料類型
11 struct LList
12 {
13     struct LinkNode header;
14     int size;
15 };
16 
17 //初始化連結清單
18 LinkList Init_LinkList()
19 {
20     struct LList* list = malloc(sizeof(struct LList));
21     if(NULL == list)
22     {
23         return NULL;
24     }
25     list->header.data = NULL;
26     list->header.next = NULL;
27     list->size = 0;
28     
29     return list;
30 }
31 //插入結點
32 void Insert_LinkList(LinkList list, int pos, void* data)
33 {
34     if(NULL == list)
35     {
36         return;
37     }
38     if(NULL == data)
39     {
40         return;
41     }    
42     
43     struct LList* mylist = (struct LList*)list;
44     
45     if(pos < 0 || pos > mylist->size)
46     {
47         pos = mylist->size;
48     }
49     
50     //查找插入位置
51     struct LinkNode* pCurrent = &(mylist->header);
52     for(int i = 0; i < pos; ++i)
53     {
54         pCurrent = pCurrent->next;    
55     }
56     
57     //建立新結點
58     struct LinkNode* newnode = malloc(sizeof(struct LinkNode));
59     newnode->data = data;
60     newnode->next = NULL;
61     
62     //新結點插入到連結清單中
63     newnode->next = pCurrent->next;
64     pCurrent->next = newnode;
65     
66     mylist->size++;
67 }
68 //周遊連結清單
69 void Foreach_LinkList(LinkList list, FOREACH myforeach)//回調函數
70 {
71     if(NULL == list)
72     {
73         return;
74     }
75     if(NULL == myforeach)
76     {
77         return;
78     }
79     
80     struct LList* mylist = (struct LList*)list;
81     
82     struct LinkNode* pCurrent = mylist->header.next;
83     
84     while(pCurrent != NULL)
85     {
86         myforeach(pCurrent->data);
87         pCurrent = pCurrent->next;
88     }
89     
90 }      

單向連結清單(版本一)——(+值删除、+位置删除、+大小、+清空、+銷毀)

單向連結清單(版本一).c

1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<stdlib.h>
 5 #include"LinkList.h"
 6 
 7 struct Person
 8 {
 9     char name[64];
10     int age;
11 };
12 
13 void myPrint(void* data)
14 {
15     struct Person* person = (struct Person*)data;
16     printf("Name:%s Age:%d\n", person->name, person->age);
17 }
18 
19 int myCompare(void* d1, void* d2)
20 {
21     struct Person* p1 = (struct Person*)d1;
22     struct Person* p2 = (struct Person*)d2;
23 
24 #if 0    
25     if(strcmp(p1->name, p2->name) == 0 && p1->age == p2->age)
26     {
27         return 1;
28     }
29     return 0;
30 #endif
31     return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age;
32 }
33 
34 void test()
35 {
36     //建立連結清單
37     LinkList list = Init_LinkList();
38     
39     //建立資料
40     struct Person p1 = {"aaa", 10};
41     struct Person p2 = {"bbb", 20};
42     struct Person p3 = {"ccc", 30};
43     struct Person p4 = {"ddd", 40};
44     struct Person p5 = {"eee", 50};
45     struct Person p6 = {"fff", 60};
46     struct Person p7 = {"ggg", 70};
47     
48     //插入資料
49     Insert_LinkList(list, 0, &p1);
50     Insert_LinkList(list, 0, &p2);
51     Insert_LinkList(list, 1, &p3);//2 3 1
52     Insert_LinkList(list, 2, &p4);//2 3 4 1
53     Insert_LinkList(list, 20, &p5);//2 3 4 1 5
54     Insert_LinkList(list, 3, &p6);//2 3 6 4 1 5
55     Insert_LinkList(list, 6, &p7);//2 3 6 4 1 7 5
56     
57     Foreach_LinkList(list, myPrint);
58     
59     printf("----------\n");
60     printf("List Size:%d\n", Size_LinkList(list));
61     RemoveByPos_LinkList(list, 3);
62     printf("----------\n");
63     Foreach_LinkList(list, myPrint);
64     
65     struct Person pDelPerson = {"ggg", 70};
66     RemoveByVal_LinkList(list, &pDelPerson, myCompare);
67     printf("----------\n");
68     Foreach_LinkList(list, myPrint);    
69     
70     //清空連結清單
71     Clear_LinkList(list);
72     printf("----------\n");
73     Foreach_LinkList(list, myPrint);    
74     
75     //銷毀連結清單
76     Destroy_LinkList(list);
77 }
78     
79 int main(){
80 
81     test();
82     
83     system("pause");
84     return EXIT_SUCCESS;
85 }      

LinkList.h

1 #pragma once
 2 
 3 #include<stdlib.h>
 4 #include<string.h>
 5 #include<stdio.h>
 6 
 7 #ifdef __cpluscplus
 8 extern "C"{
 9 #endif
10 
11 
12     
13     typedef void* LinkList;
14     typedef void(*FOREACH)(void*);
15     typedef int*(*COMPARE)(void*, void*);
16     
17     //初始化連結清單
18     LinkList Init_LinkList();
19     //插入結點
20     void Insert_LinkList(LinkList list, int pos, void* data);
21     //周遊連結清單
22     void Foreach_LinkList(LinkList list, FOREACH myforeach);
23     //按位置删除
24     void RemoveByPos_LinkList(LinkList list, int pos);
25     //按值删除
26     void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare);
27     //清空連結清單
28     void Clear_LinkList(LinkList list);
29     //大小
30     int Size_LinkList(LinkList list);
31     //銷毀連結清單
32     void Destroy_LinkList(LinkList list);
33 
34 #ifdef __cpluscplus
35 }
36 #endif      

LinkList.c

1 #include"LinkList.h"
  2 
  3 //連結清單結點資料類型
  4 struct LinkNode
  5 {
  6     void* data;
  7     struct LinkNode* next;
  8 };
  9 
 10 //連結清單資料類型
 11 struct LList
 12 {
 13     struct LinkNode header;
 14     int size;
 15 };
 16 
 17 //初始化連結清單
 18 LinkList Init_LinkList()
 19 {
 20     struct LList* list = malloc(sizeof(struct LList));
 21     if(NULL == list)
 22     {
 23         return NULL;
 24     }
 25     list->header.data = NULL;
 26     list->header.next = NULL;
 27     list->size = 0;
 28     
 29     return list;
 30 }
 31 //插入結點
 32 void Insert_LinkList(LinkList list, int pos, void* data)
 33 {
 34     if(NULL == list)
 35     {
 36         return;
 37     }
 38     if(NULL == data)
 39     {
 40         return;
 41     }    
 42     
 43     struct LList* mylist = (struct LList*)list;
 44     
 45     if(pos < 0 || pos > mylist->size)
 46     {
 47         pos = mylist->size;
 48     }
 49     
 50     //查找插入位置
 51     struct LinkNode* pCurrent = &(mylist->header);
 52     for(int i = 0; i < pos; ++i)
 53     {
 54         pCurrent = pCurrent->next;    
 55     }
 56     
 57     //建立新結點
 58     struct LinkNode* newnode = malloc(sizeof(struct LinkNode));
 59     newnode->data = data;
 60     newnode->next = NULL;
 61     
 62     //新結點插入到連結清單中
 63     newnode->next = pCurrent->next;
 64     pCurrent->next = newnode;
 65     
 66     mylist->size++;
 67 }
 68 //周遊連結清單
 69 void Foreach_LinkList(LinkList list, FOREACH myforeach)//回調函數
 70 {
 71     if(NULL == list)
 72     {
 73         return;
 74     }
 75     if(NULL == myforeach)
 76     {
 77         return;
 78     }
 79     
 80     struct LList* mylist = (struct LList*)list;
 81     
 82     struct LinkNode* pCurrent = mylist->header.next;
 83     
 84     while(pCurrent != NULL)
 85     {
 86         myforeach(pCurrent->data);
 87         pCurrent = pCurrent->next;
 88     }
 89     
 90 }
 91 
 92 //按位置删除
 93 void RemoveByPos_LinkList(LinkList list, int pos)
 94 {
 95     if(NULL == list)
 96     {
 97         return;
 98     }
 99     struct LList* mylist = (struct LList*)list;
100     
101     if(pos < 0 || pos > mylist->size - 1)
102     {
103         return;
104     }
105     //找位置
106     struct LinkNode* pCurrent = &(mylist->header);
107     for(int i = 0; i < pos; ++i)
108     {
109         pCurrent = pCurrent->next;
110     }
111     
112     //先儲存待删除結點
113     struct LinkNode* pDel = pCurrent->next;
114     //重建立立待删除結點的前驅和後繼結點關系
115     pCurrent->next = pDel->next;
116     //釋放删除結點記憶體
117     free(pDel);
118     pDel = NULL;
119     
120     mylist->size--;
121 }
122 //按值删除
123 void RemoveByVal_LinkList(LinkList list, void* data, COMPARE compare)
124 {
125     if(NULL == list)
126     {
127         return;
128     }    
129     if(NULL == data)
130     {
131         return;
132     }
133     if(NULL == compare)
134     {
135         return;
136     }
137     
138     struct LList* mylist = (struct LList*)list;
139     //輔助指針變量
140     struct LinkNode* pPrev = &(mylist->header);
141     struct LinkNode* pCurrent = pPrev->next;
142     while(pCurrent != NULL)
143     {
144         if(compare(pCurrent->data, data))
145         {
146             //找到了
147             pPrev->next = pCurrent->next;
148             //釋放删除結點記憶體
149             free(pCurrent);
150             pCurrent = NULL;
151             mylist->size--;
152             break;
153         }
154         
155         pPrev = pCurrent;
156         pCurrent = pCurrent->next;
157     }
158 }
159 //清空連結清單
160 void Clear_LinkList(LinkList list)
161 {
162     if(NULL == list)
163     {
164         return;
165     }
166     struct LList* mylist = (struct LList*)list;
167     
168     //輔助指針變量
169     struct LinkNode* pCurrent = mylist->header.next;
170     
171     while(pCurrent != NULL)
172     {
173         //先緩存下一個結點的位址
174         struct LinkNode* pNext = pCurrent->next;
175         //釋放目前結點記憶體
176         free(pCurrent);
177         
178         pCurrent = pNext;
179     }
180     mylist->header.next = NULL;
181     //把size更新
182     mylist->size = 0;
183     
184 }
185 //大小
186 int Size_LinkList(LinkList list)
187 {
188     if(NULL == list)
189     {
190         return -1;
191     }
192     struct LList* mylist = (struct LList*)list;
193     
194     return mylist->size;
195 }
196 //銷毀連結清單
197 void Destroy_LinkList(LinkList list)
198 {
199     if(NULL == list)
200     {
201         return;
202     }
203     
204     //清空連結清單
205     Clear_LinkList(list);
206     free(list);
207     list = NULL;
208 }      

 練習3:單向連結清單(版本二)

記憶體模型圖如下:

c語言提高學習筆記——03-c提高08day_資料結構
1 #define _CRT_SECURE_NO_WARNINGS
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<stdlib.h>
 5 
 6 struct LinkNode
 7 {
 8     struct LinkNode* next;
 9 };
10 
11 struct Person
12 {
13     struct LinkNode node;//給四個位元組存位址
14     char name[64];
15     int age;
16 };
17 
18 void test()
19 {
20     struct Person p1 = {NULL, "aaa", 10};
21     struct Person p2 = {NULL, "bbb", 20};
22     struct Person p3 = {NULL, "ccc", 30};
23     struct Person p4 = {NULL, "ddd", 40};
24     struct Person p5 = {NULL, "eee", 50};
25     
26     struct LinkNode* pp1 = (struct LinkNode*)&p1;
27     struct LinkNode* pp2 = (struct LinkNode*)&p2;
28     struct LinkNode* pp3 = (struct LinkNode*)&p3;
29     struct LinkNode* pp4 = (struct LinkNode*)&p4;
30     struct LinkNode* pp5 = (struct LinkNode*)&p5;
31     
32     pp1->next = pp2;
33     pp2->next = pp3;
34     pp3->next = pp4;
35     pp4->next = pp5;
36     pp5->next = NULL;
37     
38     struct LinkNode* pCurrent = pp1;
39     while(pCurrent != NULL)
40     {
41         struct Person* person = (struct Person*)pCurrent;
42         printf("Name:%s Age:%d\n", person->name, person->age);
43         
44         pCurrent = pCurrent->next;
45     }
46     
47 }
48 
49 int main(){
50 
51     test();
52     
53     system("pause");
54     return EXIT_SUCCESS;
55 }      

繼續閱讀