线性结构之单链表基本操作!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 本程序实现单链表的创建、遍历、插入、删除、排序 3 C语言在Visual Studio 2013下编译通过 4 */ 5 6 #include <stdint.h> 7 #include <malloc.h> 8 #include <stdlib.h> 9 #include <stdbool.h> 10 11 12 //定义单链表的数据结构 13 typedef struct TagNode 14 { 15 int Date; //数据域定义为int类型 16 17 struct TagNode * pNext; //指针域为TagNode类型 18 19 }Node, *PNode; 20 21 22 23 //函数声明 24 25 int getLength(PNode pHead); 26 PNode createLinkedListForTail(void); 27 PNode createLinkedListForHead(void); 28 bool insertNode(PNode pHead, int i, int data); 29 bool deleteNode(PNode pHead, int i); 30 void storeForBubble(PNode pHead); 31 void traversal(PNode pHead); 32 33 //main函数 34 int main(void) 35 { 36 int pos = 0; 37 int newData = 0; 38 39 PNode head = NULL; 40 41 //head = createLinkedListForTail(); 42 //printf("尾插法排序前: "); 43 //traversal(head); 44 45 //storeForBubble(head); 46 //printf("尾插法排序后: "); 47 //traversal(head); 48 //free(head); 49 50 //printf(" "); 51 52 //head = createLinkedListForHead(); 53 //printf("头插法排序前: "); 54 //traversal(head); 55 56 //storeForBubble(head); 57 //printf("头插法排序后: "); 58 //traversal(head); 59 //free(head); 60 61 //printf("重新创建链表: "); 62 //head = createLinkedListForTail(); 63 //printf("输入要插入的位置: Pos="); 64 //scanf("%d", &pos); 65 //printf("输入要插入的新节点数据值: Data="); 66 //scanf("%d", &newData); 67 //insertNode(head, pos, newData); 68 //traversal(head); 69 70 //head = createLinkedListForTail(); 71 //traversal(head); 72 //printf("输入要删除的节点位置: Pos="); 73 //scanf("%d", &pos); 74 //deleteNode(head, pos); 75 //traversal(head); 76 //free(head); 77 getchar(); 78 } 79 80 //求表长 81 int getLength(PNode pHead) 82 { 83 int length = 0; 84 if (NULL == pHead) 85 { 86 printf("链表不存在啊! "); 87 return -1; 88 } 89 90 PNode node = pHead->pNext; 91 while (NULL != node) 92 { 93 ++length; 94 node = node->pNext; 95 } 96 97 return length; 98 } 99 100 //尾插法 创建单链表,并返回该链表的头节点 101 PNode createLinkedListForTail(void) 102 { 103 int length; //表长 104 int value; //数据域值 105 106 printf("-----这是尾插法:----- "); 107 108 //创建头节点 109 PNode pHead = (PNode)malloc(sizeof(Node)); 110 if (NULL == pHead) 111 { 112 printf("初始化链表失败!"); 113 exit(-1); 114 } 115 116 //并初始化一个空链表 117 pHead->pNext = NULL; 118 119 //指针pLast,始终指向最后一个节点,开始时指向头节点 120 PNode pLast = pHead; 121 122 123 printf("请输入单链表的长度:Length= "); 124 scanf("%d", &length); 125 126 if (length < 0) 127 { 128 printf("输入不合法!"); 129 return NULL; 130 } 131 else if (length == 0) 132 { 133 printf("只包含头节点的空链表!"); 134 return pHead; 135 } 136 137 138 for (int i = 0; i < length; i++) 139 { 140 printf("请输入第%d个节点的值: ", i + 1); 141 142 scanf("%d", &value); 143 144 PNode newNode = (PNode)malloc(sizeof(Node));//新的节点 145 if (NULL == newNode) 146 { 147 printf("创建节点失败!"); 148 exit(-1); 149 } 150 151 newNode->Date = value; 152 pLast->pNext = newNode; 153 newNode->pNext = NULL; 154 155 pLast = newNode; //指向最后一个节点 156 } 157 158 return pHead; 159 } 160 161 //头插法 创建单链表, 并返回该链表的头节点 162 PNode createLinkedListForHead(void) 163 { 164 int length; //表长 165 int value; //数据域值 166 167 printf("-----这是头插法:----- "); 168 169 //创建头节点 170 PNode pHead = (PNode)malloc(sizeof(Node)); 171 if (NULL == pHead) 172 { 173 printf("初始化链表失败!"); 174 exit(-1); 175 } 176 177 //并初始化一个空链表 178 pHead->pNext = NULL; 179 180 printf("请输入单链表的长度:Length= "); 181 scanf("%d", &length); 182 183 if (length < 0) 184 { 185 printf("输入不合法!"); 186 return NULL; 187 } 188 else if (length == 0) 189 { 190 printf("只包含头节点的空链表!"); 191 return pHead; 192 } 193 194 for (int i = 0; i < length; i++) 195 { 196 printf("请输入第%d个节点的值: ", i + 1); 197 198 scanf("%d", &value); 199 200 PNode newNode = (PNode)malloc(sizeof(Node));//新的节点 201 if (NULL == newNode) 202 { 203 printf("创建节点失败!"); 204 exit(-1); 205 } 206 207 newNode->Date = value; 208 newNode->pNext = pHead->pNext; 209 210 pHead->pNext = newNode; 211 } 212 213 return pHead; 214 } 215 216 //对单链表冒泡排序 升序 217 void storeForBubble(PNode pHead) 218 { 219 if (NULL == pHead) 220 { 221 printf("链表不存在啊! "); 222 return; 223 } 224 225 int tempData = 0; 226 PNode pM; 227 PNode pN; 228 229 for (pM = pHead->pNext; NULL != pM; pM = pM->pNext) 230 { 231 for (pN = pM->pNext; NULL != pN; pN = pN->pNext) 232 { 233 if (pM->Date > pN->Date) 234 { 235 tempData = pN->Date; 236 pN->Date = pM->Date; 237 pM->Date = tempData; 238 } 239 } 240 } 241 } 242 243 //在第i个节点之前插入新节点 244 bool insertNode(PNode pHead, int i, int data) 245 { 246 if (NULL == pHead) 247 { 248 printf("链表不存在啊! "); 249 return false; 250 } 251 252 //-----这里不对链表求表长来判断被插入的位置i是否合法,效率高,理解困难!----- 253 254 int k = 0; 255 PNode p = pHead->pNext; 256 PNode newNode = (PNode)malloc(sizeof(Node)); 257 258 while (NULL != p && k < i - 1) 259 { 260 p = p->pNext; 261 ++k; 262 } 263 264 if (NULL == p || k > i - 1) 265 return false; 266 267 268 if (NULL == newNode) 269 { 270 printf("创建节点失败!"); 271 exit(-1); 272 } 273 274 newNode->Date = data; 275 PNode tmp = p->pNext; 276 p->pNext = newNode; 277 newNode->pNext = tmp; 278 279 return true; 280 } 281 282 //删除第i个节点 283 bool deleteNode(PNode pHead, int i) 284 { 285 if (NULL == pHead) 286 { 287 printf("链表不存在啊! "); 288 return false; 289 } 290 291 292 int k = 0; 293 PNode p = pHead; 294 PNode pDel = NULL; 295 296 while (NULL != p->pNext && k < i - 1) 297 { 298 p = p->pNext; 299 ++k; 300 } 301 302 if (NULL == p->pNext || k > i - 1) 303 return false; 304 305 pDel = p->pNext; 306 p->pNext = p->pNext->pNext; 307 308 free(pDel); 309 310 return true; 311 } 312 313 //遍历单链表 314 void traversal(PNode pHead) 315 { 316 if (NULL == pHead) 317 { 318 printf("链表不存在啊! "); 319 return; 320 } 321 322 PNode p = pHead->pNext; 323 while (NULL != p) 324 { 325 printf("节点: %d , 地址: %#X , p->next: %#X ", p->Date, p, p->pNext); 326 p = p->pNext; 327 } 328 }