数据结构之链表-链表实现及常用操作(C++篇)
C语言实现单链表,主要功能为空链表创建,链表初始化(头插法),链表元素读取,按位置插入,(有序链表)按值插入,按位置删除,按值删除,清空链表,销毁链表。
关键思路:(1)将结点创建结构体;(2)链表中添加头结点,以便统一操作;(3)使用结点一级指针和二级指针的异同点;(4)链表的最小操作单位是结点;(5)操作的起始位置是头结点还是第一个结点,及起始索引是0还是1.
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <time.h> 4 5 //涉及到结构体自引用 6 typedef struct Node{ 7 int data; 8 struct Node *next; 9 }Node; 10 11 //创建空链表 12 //必须用二级指针,涉及到头指针的创建 13 int iniList(Node **List){ 14 *List = (Node *)malloc(sizeof(Node)); 15 if (NULL == *List){ 16 return 0; 17 } 18 19 (*List)->next = NULL; //创建头结点 20 return 1; 21 } 22 23 //初始化链表(头插法) 24 //必须二级指针 25 int iniListHead(Node **List, int n){ 26 *List = (Node *)malloc(sizeof(Node)); 27 if (NULL == *List){ 28 return 0; 29 } 30 (*List)->next = NULL; 31 srand(time(0)); 32 33 int i = 0; 34 while (i < n){ 35 Node *tmpNode = (Node *)malloc(sizeof(Node)); 36 if (NULL == tmpNode){ 37 return 0; 38 } 39 tmpNode->data = rand() % 100 + 1; 40 tmpNode->next = (*List)->next; 41 (*List)->next = tmpNode; 42 43 44 ++i; 45 } 46 return 1; 47 } 48 49 //初始化链表(尾插法) 50 //必须二级指针 51 //需要借助辅助变量pCurrent,将每次尾插的新元素当做当前元素 52 int iniListTail(Node **List, int n){ 53 *List = (Node *)malloc(sizeof(Node)); 54 if (NULL == *List){ 55 return 0; 56 } 57 (*List)->next = NULL; 58 srand(time(0)); 59 60 Node *pCurrent = *List; 61 62 int i = 0; 63 while (i < n){ 64 Node *tmpNode = (Node *)malloc(sizeof(Node)); 65 if (NULL == tmpNode){ 66 return 0; 67 } 68 tmpNode->data = rand() % 100 + 1; 69 tmpNode->next = NULL; 70 pCurrent->next = tmpNode; 71 pCurrent = tmpNode; 72 73 ++i; 74 } 75 return 1; 76 } 77 78 //清空链表(不删除头结点) 79 //一级,二级指针均可 80 //首先找到链表地址,然后移动至表尾 81 //判断条件为指针域是否为空,即到达结尾 82 int deleteList(Node *List){ 83 84 //这种方法无法删除尾结点 85 //Node *p= List; 86 //Node *q = NULL; 87 // 88 //while (p->next){ 89 // q = p; 90 // free(p); 91 // p = q->next; 92 //} 93 94 Node *p = List->next; 95 Node *q = NULL; 96 97 while (p){ 98 q = p->next; 99 free(p); 100 p = q; 101 } 102 103 List->next = NULL; 104 return 1; 105 } 106 107 //销毁链表 108 //必须使用二级指针,销毁头结点和头指针 109 //最后将链表头指针置空 110 int desrotyList(Node **List){ 111 112 Node *p = *List; 113 Node *q = NULL; 114 115 //如果为空链表,直接删除头结点 116 //如果不是空链表,从头结点开始删除 117 while (p){ 118 q = p->next; 119 free(p); 120 p = q; 121 } 122 (*List) = NULL; 123 124 //下面是从第一个结点开始删除 125 //最后释放掉头结点 126 //Node *p = (*List)->next; 127 //Node *q = NULL; 128 // 129 //while (p){ 130 // q = p->next; 131 // free(p); 132 // p = q; 133 //} 134 //free(*List); 135 //(*List) = NULL; 136 137 return 1; 138 } 139 140 //链表获取元素 141 //一级,二级指针均可 142 //头结点无意义,从第一个结点开始遍历,i从1开始 143 //每次都指向下一结点,到pos-1即可 144 int getList(Node *List, int pos, int *element){ 145 Node *p = List->next; 146 147 int i = 1; 148 while (p && i < pos){ 149 p = p->next; 150 ++i; 151 } 152 *element = p->data; 153 return 1; 154 } 155 156 //链表按位置插入 157 //一级,二级指针均可 158 //从头结点开始,有可能插入在第一个位置,遍历从1开始 159 int insertListPos(Node *List, int pos, int value){ 160 Node *p = List; 161 162 int i = 1; 163 while (p && i < pos){ 164 p = p->next; 165 ++i; 166 } 167 Node *tmpNode = (Node *)malloc(sizeof(Node)); 168 tmpNode->data = value; 169 tmpNode->next = p->next; 170 p->next = tmpNode; 171 return 1; 172 } 173 174 //有序链表,按值插入 175 //一二级指针均可 176 int insertListValue(Node *List, int value){ 177 Node *pCur = List->next; 178 Node *pPer = List; 179 while (pCur && pCur->data < value){ 180 pPer = pCur; 181 pCur = pCur->next; 182 } 183 184 Node *tmpNode = (Node *)malloc(sizeof(Node)); 185 if (NULL == tmpNode){ 186 return 0; 187 } 188 tmpNode->data = value; 189 tmpNode->next = pPer->next; 190 pPer->next = tmpNode; 191 return 1; 192 } 193 194 //链表按位置删除 195 //一二级指针均可 196 //记得释放结点内存 197 //如果删除第一个结点,需要操纵头结点 198 int deleteListPos(Node *List, int pos){ 199 Node *p = List; 200 201 int i = 1; 202 while (p && i < pos){ 203 p = p->next; 204 ++i; 205 } 206 if (NULL == p->next) 207 return 0; 208 209 Node *tmpNode = p->next; 210 p->next = p->next->next; 211 212 free(tmpNode); 213 return 1; 214 } 215 216 //链表按值删除元素 217 //一二级指针均可 218 //从第一个结点开始 219 int deleteListValue(Node *List, int value){ 220 Node *pCur = List->next; 221 Node *pPer = List; 222 223 while (pCur && pCur->data != value){ 224 pPer = pCur; 225 pCur = pCur->next; 226 } 227 if (pCur == NULL){ //空链表不删除任何结点 228 return 0; 229 } 230 else{ 231 pPer->next = pCur->next; 232 free(pCur); 233 } 234 return 1; 235 } 236 237 int main(){ 238 239 Node *testList = NULL; 240 iniList(&testList); 241 //iniListHead(&testList, 3); 242 //iniListTail(&testList, 3); 243 244 245 insertListPos(testList, 1, 2); 246 insertListPos(testList, 2, 4); 247 insertListPos(testList, 3, 5); 248 insertListPos(testList, 4, 10); 249 //insertListPos(testList, 1, 1); 250 insertListValue(testList, 1); 251 252 //deleteListPos(testList, 1); 253 //deleteListValue(testList, 4); 254 255 //deleteList(testList); 256 257 //printf("%d\n", testList); 258 //desrotyList(&testList); 259 //printf("%d\n", testList); 260 261 Node * tmpNode = testList->next; 262 while (tmpNode){ 263 printf("%d\n", tmpNode->data); 264 tmpNode = tmpNode->next; 265 } 266 267 printf("----------------------\n"); 268 269 int a = 0; 270 getList(testList, 2, &a); 271 printf("%d\n", a); 272 273 system("pause"); 274 275 return 0; 276 }