1.使用头节点建立和操作单链表
使用头节点的方式来建立单链表,以及一些基本的单链表操作函数。
分别使用二级指针和一级指针的方式来同时实现功能函数:
1 /* 2 使用头节点方法来建立或操作单链表 3 */ 4 #include <stdio.h> 5 #include <stdlib.h> 6 typedef struct node 7 { 8 int data; 9 struct node *p_next; 10 }node; 11 //创建链表,返回链表头 12 node* Creat() 13 { 14 node *p_head = malloc(sizeof(node)); 15 p_head->p_next = NULL; 16 return p_head; 17 } 18 /*在头部插入一个新节点*/ 19 20 void Insert_FirstPos_P(node* L,int num) 21 { 22 node* p_head = L; 23 //先保存链表内第一个有效节点 24 node* p_tmp = p_head->p_next; 25 //新节点前后连接 26 p_head->p_next = malloc(sizeof(sizeof(node))); 27 p_head->p_next->data = num; 28 p_head->p_next->p_next = p_tmp; 29 } 30 31 32 /*在尾部插入一个新节点*/ 33 //使用一级指针 34 void Insert_EndPos_P(node* L,int num) 35 { 36 node* p_head = L; 37 node* p_tmp = p_head; 38 //遍历到链表尾部(最后一个有效节点的位置上) 39 while(p_tmp->p_next) 40 { 41 p_tmp = p_tmp->p_next; 42 } 43 p_tmp->p_next = malloc(sizeof(node)); 44 p_tmp->p_next->data = num; 45 p_tmp->p_next->p_next = NULL; 46 } 47 //使用二级指针 48 void Insert_EndPos_PP(node* L,int num) 49 { 50 node* p_head = L; 51 node** p_tmp = &p_head; 52 //直接遍历到链表尾部后空位置(最后一个有效节点的后的空位置) 53 while(*p_tmp) 54 { 55 p_tmp = &((*p_tmp)->p_next); 56 } 57 *p_tmp = malloc(sizeof(node)); 58 (*p_tmp)->p_next = NULL; 59 (*p_tmp)->data = num; 60 } 61 62 /*在编号为pos的位置处插入新节点*/ 63 //使用一级指针 64 65 void Insert_Pos_P(node* L,int pos,int num) 66 { 67 int count = 0; 68 node* p_head = L; 69 node* p_tmp = p_head; 70 node* p_tmp2 = NULL; 71 while(p_tmp) 72 { 73 //遍历找到pos-1处的节点,进行连接 74 if(count == pos-1 && p_tmp->p_next) 75 { 76 printf("此时count=%d ",count); 77 p_tmp2 = p_tmp->p_next; 78 p_tmp->p_next = malloc(sizeof(node)); 79 p_tmp->p_next->data = num; 80 p_tmp->p_next->p_next = p_tmp2; 81 break; 82 } 83 p_tmp = p_tmp->p_next; 84 count++; 85 } 86 if(p_tmp) 87 { 88 printf("插入成功"); 89 } 90 else 91 { 92 printf("插入失败"); 93 } 94 } 95 //使用二级指针 96 void Insert_Pos_PP(node* L,int pos,int num) 97 { 98 int count = 0; 99 node* p_head = L; 100 node** p_tmp = &p_head; 101 node* p_tmp2 = NULL; 102 while(*p_tmp) 103 { 104 if(count == pos) 105 { 106 p_tmp2 = *p_tmp; 107 *p_tmp = malloc(sizeof(node)); 108 (*p_tmp)->p_next = p_tmp2; 109 (*p_tmp)->data = num; 110 break; 111 } 112 p_tmp = &((*p_tmp)->p_next); 113 count++; 114 } 115 if(*p_tmp) 116 { 117 printf("插入成功"); 118 } 119 else 120 { 121 printf("无此编号,插入失败"); 122 } 123 } 124 125 126 //根据编号获得有效数据 127 int Get_Data(node* L,int pos) 128 { 129 int count = 0; 130 node* p_head = L; 131 node* p_tmp = p_head->p_next; 132 while(p_tmp) 133 { 134 count++; 135 if(count == pos) 136 { 137 printf("此时count为编号%d\n",count); 138 printf("编号位为%d处的节点中的有效数字为:%d",count,p_tmp->data); 139 break; 140 } 141 p_tmp = p_tmp->p_next; 142 } 143 if(p_tmp) 144 { 145 return p_tmp->data; 146 } 147 else 148 { 149 printf("无此编号"); 150 return -1; 151 } 152 } 153 154 //打印链表中有效节点的个数 155 int PrintNodeCount(node* L) 156 { 157 int count = 0; 158 node* p_head = L; 159 node* p_tmp = p_head->p_next; 160 while(p_tmp) 161 { 162 count++; 163 p_tmp = p_tmp->p_next; 164 } 165 return count; 166 } 167 /*销毁链表*/ 168 void Destory_P(node* L) 169 { 170 node* p_head = L; 171 node* p_tmp = NULL; 172 while(p_head->p_next)//如果头指针后面有节点,则删除 173 { 174 p_tmp = p_head->p_next; 175 p_head->p_next = p_head->p_next->p_next; 176 free(p_tmp); 177 p_tmp = NULL; 178 } 179 } 180 181 /*删除指定编号上的节点*/ 182 //使用一级指针 183 void RemoveNode_Pos_P(node* L, int pos) 184 { 185 int count = 0; 186 node* p_head = L; 187 node* p_tmp = p_head; 188 node* p_tmp2 = NULL; 189 while(p_tmp) 190 { 191 if(count == pos-1 && p_tmp->p_next) 192 { 193 p_tmp2 = p_tmp->p_next; 194 p_tmp->p_next = p_tmp->p_next->p_next; 195 free(p_tmp2); 196 p_tmp2 = NULL; 197 break; 198 } 199 p_tmp = p_tmp->p_next; 200 count++; 201 } 202 if(p_tmp) 203 { 204 printf("删除成功!"); 205 } 206 else 207 { 208 printf("无此编号,删除失败"); 209 } 210 } 211 //使用二级指针 212 void RemoveNode_Pos_PP(node* L, int pos) 213 { 214 int count = 0; 215 node* p_head = L; 216 node** p_tmp = &p_head; 217 node* p_tmp2 = NULL; 218 while(*p_tmp) 219 { 220 if(count == pos) 221 { 222 p_tmp2 = *p_tmp; 223 *p_tmp = (*p_tmp)->p_next; 224 free(p_tmp2); 225 // printf("删除成功!"); 226 break; 227 } 228 p_tmp =&((*p_tmp)->p_next); 229 count++; 230 } 231 /* 这个是错误的:如果pos是尾编号,则退出循环时*p_tmp也为NULL,所以下面判断不成立 232 if(*p_tmp) 233 { 234 printf("删除成功"); 235 } 236 else 237 { 238 printf("无此编号,删除失败!"); 239 } 240 */ 241 if(count == pos) 242 { 243 printf("删除成功"); 244 } 245 else 246 { 247 printf("无此编号,删除失败"); 248 } 249 } 250 251 //打印链表 252 void PrintList(node* L) 253 { 254 node* p_tmp = L->p_next;//从第一个有效节点开始遍历 255 while(p_tmp) 256 { 257 printf("%d ",p_tmp->data); 258 p_tmp = p_tmp->p_next; 259 } 260 }