手把手写数据结构之双向链表操作
1 define NAME_LEN 20 //名字最大长度 2 3 //函数入口检测(宏) 4 #define TEST(arg) if(arg == NULL){\ 5 printf("Invalid arg..................\n");\ 6 return -1;\ 7 } 8 9 typedef enum sex//性别封装 10 { 11 b , //男 12 g , //女 13 }E_SEX; 14 15 typedef struct stu_info//学生信息封装 16 { 17 int num; //学号 18 char name[NAME_LEN+1]; //姓名 19 E_SEX sex; //性别 20 }STU_INFO; 21 22 typedef struct stu_node//结点信息 23 { 24 STU_INFO stu; //学生信息 25 struct stu_node *prev; //结点指针前驱 26 struct stu_node *next; //结点指针后驱 27 }NODE; 28 29 30 typedef struct link_info 31 { 32 int node_count;//结点个数 33 NODE *head; //指向首元结点的指针 34 }LINK_INFO; 35 36 37 38 39 40 41 42 //创建结点 43 static NODE *__Create_Node__(STU_INFO stu) 44 { 45 NODE *new_node = (NODE *)malloc(sizeof(NODE)); 46 if(NULL == new_node) 47 { 48 perror("Create_Node"); 49 return NULL; 50 } 51 52 new_node ->stu = stu; 53 new_node->next = NULL; 54 new_node->prev = NULL; 55 56 return new_node; 57 } 58 59 /************************************************* 60 *Des: 查找某个结点是否存在 61 *Ret: 成功返回结点,失败返回NULL; 62 **************************************************/ 63 static NODE *__Find_Node__(LINK_INFO *plist, int num) 64 { 65 if(NULL == plist) 66 { 67 printf("Invalid arg.......\n"); 68 return NULL; 69 } 70 71 NODE *pnode = plist->head; 72 while(NULL != pnode) 73 { 74 if(pnode->stu.num == num) 75 break; 76 pnode = pnode->next; 77 } 78 79 return pnode; 80 } 81 82 /************************************************* 83 *Des: 创建学生信息链表 84 *Ret: 成功返回0,失败返回-1; 85 **************************************************/ 86 int Stu_Ceate_Link(LINK_INFO **plist) 87 { 88 TEST(plist);//函数入口检测 89 90 *plist = (LINK_INFO *)malloc(sizeof(LINK_INFO)); 91 if(NULL == *plist) 92 { 93 perror("Create Link"); 94 return -1; 95 } 96 97 (*plist)->node_count = 0; 98 (*plist)->head = NULL; 99 100 return 0; 101 } 102 103 /************************************************* 104 *Des: 判断学生信息链表是否为空 105 *Ret: 真空:1 ,假空:0 106 **************************************************/ 107 int Stu_Is_Empty(LINK_INFO *plist) 108 { 109 return ((NULL == plist->head) ? 1 : 0); 110 } 111 112 /************************************************* 113 *Des: 添加结点到链表(按num排好序) 114 *Ret: 成功返回0,失败返回-1; 115 **************************************************/ 116 int Stu_Add_Node(LINK_INFO *plist, STU_INFO stu) 117 { 118 TEST(plist);//函数入口检测 119 120 NODE *tmpnode = NULL, *pnode = plist->head; 121 122 if(__Find_Node__(plist, stu.num) != NULL) 123 { 124 printf("Have this Node!\n"); 125 return -1; 126 } 127 128 //创建结点 129 NODE *new_node = __Create_Node__(stu); 130 if(NULL == new_node) 131 return -1; 132 133 if(Stu_Is_Empty(plist))//当链表为空 134 { 135 plist->head = new_node; 136 } 137 else //链表非空 138 { 139 while(NULL != pnode) 140 { 141 if(pnode->stu.num > stu.num) 142 break; 143 tmpnode = pnode; 144 pnode = pnode->next; 145 } 146 if(NULL == pnode)//添加到尾结点后 147 { 148 tmpnode->next = new_node; 149 new_node->prev = tmpnode; 150 } 151 else 152 { 153 if(NULL == tmpnode)//添加到头结点前 154 { 155 new_node->next = plist->head; 156 plist->head->prev = new_node; 157 plist->head = new_node; 158 } 159 else//其它 160 { 161 tmpnode->next = new_node; 162 new_node->prev = tmpnode; 163 new_node->next = pnode; 164 pnode->prev = new_node; 165 } 166 } 167 168 } 169 170 plist->node_count++; 171 172 return 0; 173 } 174 175 /************************************************* 176 *Des: 删除学生信息 177 *Ret: 成功返回0,失败返回-1; 178 **************************************************/ 179 int Stu_Delete_Node(LINK_INFO *plist, int num) 180 { 181 TEST(plist);//函数入口检测 182 183 NODE *pnode = NULL; 184 if(NULL == (pnode = __Find_Node__(plist, num)))//1 185 { 186 return -1; 187 } 188 189 //只有1个节点 190 if(pnode == plist->head && pnode->next == NULL) 191 { 192 plist->head = NULL; 193 } 194 195 //2.是头结点 196 else if(pnode == plist->head) 197 { 198 plist->head = pnode->next; 199 pnode->next->prev = NULL; 200 //plist->head->prev = NULL; 201 } 202 //3.是最后一个节点 203 else if(pnode->next == NULL) 204 { 205 pnode->prev->next = NULL; 206 } 207 //4.其他节点 208 else 209 { 210 pnode->prev->next = pnode->next; 211 pnode->next->prev = pnode->prev; 212 } 213 214 free(pnode); 215 216 plist->node_count--; 217 218 return 0; 219 } 220 221 222 /************************************************* 223 *Des: 遍历学生信息 224 *Ret: 成功返回0,失败返回-1; 225 **************************************************/ 226 int Stu_Traverse(LINK_INFO *plist) 227 { 228 TEST(plist);//函数入口检测 229 230 if(Stu_Is_Empty(plist)) 231 { 232 printf("The list is empty!\n"); 233 return -1; 234 } 235 236 NODE *pnode = plist->head; 237 printf("###################################################\n"); 238 printf("num\t name\t\tsex\t\n"); 239 while(NULL != pnode) 240 { 241 if(pnode->stu.sex == 0) 242 pnode->stu.sex += 98; 243 else 244 pnode->stu.sex += 102; 245 246 printf("%-10d%-10s\t%c\n", pnode->stu.num, 247 pnode->stu.name, pnode->stu.sex); 248 pnode = pnode->next; 249 } 250 251 printf("###################################################\n"); 252 253 return 0; 254 } 255 256 /************************************************* 257 *Des: 清空链表操作 258 *Ret: 成功返回0,失败返回-1; 259 **************************************************/ 260 int Stu_Empty_Link(LINK_INFO *plist) 261 { 262 TEST(plist);//函数入口检测 263 264 if(Stu_Is_Empty(plist)) 265 { 266 printf("The is list is empty!\n"); 267 return -1; 268 } 269 270 NODE *tmpnode = NULL, *pnode = plist->head; 271 while(pnode != NULL) 272 { 273 tmpnode= pnode; 274 pnode = pnode->next; 275 } 276 277 plist->head = NULL; 278 plist->node_count = 0; 279 280 return 0; 281 } 282 283 284 /************************************************* 285 *Des: 销毁链表 286 *Ret: 成功返回0,失败返回-1; 287 **************************************************/ 288 int Stu_Destory_Link(LINK_INFO **plist) 289 { 290 TEST(plist); 291 292 //清空链表 293 if(Stu_Empty_Link(plist) < 0) 294 return -1; 295 296 free(*plist); 297 298 *plist = NULL; 299 300 return 0; 301 }