ps:list链表 node节点
在链表中节点就是一个个的结构体
堆空间由于在申请内存时,地址是随机的,所以要用链表的方式将其连接起来,但是链表头的地址要知道.
每个节点包含两个部分:数据区和地址区,其中指向自身类型节点的指针叫做地址域,定义结构体时别忘了随便给head附上NULL地址.(尾地址不用单独定义,因为它是在节点内的)
由于最后一个节点之后没有指向的下一个节点,所以其地址域为NULL,如果是空链表,就是只定义了一个结构体,什么数据都没有,这个时候把表头的地址初始化定为NULL
节点的插入有头插法和尾插法:
头插法就是不断地在头部位置添加节点,如上图也就是新添加的节点的地址域要指向原来的头地址,新的头地址要改为新插入的节点的地址.这样刚好在添加第一个节点的时候,初始化的头地址变为了第一个节点的地址域也就是NULL,也就是尾指针变为了NULL.调用链表中的数据时,要定义一个节点类型的指针,它指向要和头地址的指向相同,然后利用它调用第一个节点,在将此节点的地址域赋给它,再次利用它调用下一个节点...只到它为NULL指针为止.
#include<stdio.h>
#include<stdlib.h>struct Node{ int data; struct Node* pNext;};struct Node* pHead = NULL;void AddHead(int data){ struct Node* p = (struct Node*)malloc(sizeof(struct Node)); p->data = data; p->pNext = pHead; pHead = p;}void Print(){ struct Node* ptemp = pHead; while (ptemp != NULL) { printf("%d ", ptemp->data); ptemp = ptemp->pNext; }}void main(){ AddHead(1); AddHead(2); AddHead(3); Print();}尾插法:尾插法相对来说比较麻烦,多了一个判断是不是第一个节点的过程
#include#include struct Node{ int data; struct Node* pNext;};struct Node* pHead = NULL;void AddHead(int data){ struct Node* p = (struct Node*)malloc(sizeof(struct Node)); p->data = data; p->pNext = pHead; pHead = p;}void AddTail(int data){ struct Node* p = (struct Node*)malloc(sizeof(struct Node)); p->data = data; if (pHead == NULL) pHead = p; else { struct Node* ptemp = pHead; while (ptemp->pNext != NULL) { ptemp = ptemp->pNext; } ptemp->pNext = p; } p->pNext = NULL;}void Print(){ struct Node* ptemp = pHead; while (ptemp != NULL) { printf("%d ", ptemp->data); ptemp = ptemp->pNext; }}void main(){ AddTail(1); AddTail(2); Print();}
链表中删除节点(数据结构中删除是最麻烦的)
按照上图的方法,中间和尾部的节点删除都可以成功,但是可以发现在删除头部第一个节点后打印会出错,是因为head前面没有节点了,头地址还没被改变,所以要在循环寻找数据之前,写一个if语句专门针对一下删除第一个节点的情况。还可以发现在整个链表为空的时候删除也会出错,所以也进行了特殊处理.所以在一个功能中要测试头,中间,尾和空四个特殊位置
#include<stdio.h>
#include<stdlib.h>struct Node{ int data; struct Node* pNext;};struct Node* pHead = NULL;void AddHead(int data){ struct Node* p = (struct Node*)malloc(sizeof(struct Node)); p->data = data; p->pNext = pHead; pHead = p;}void AddTail(int data){ struct Node* p = (struct Node*)malloc(sizeof(struct Node)); p->data = data; if (pHead == NULL) pHead = p; else { struct Node* ptemp = pHead; while (ptemp->pNext != NULL) { ptemp = ptemp->pNext; } ptemp->pNext = p; } p->pNext = NULL;}void Print(){ struct Node* ptemp = pHead; while (ptemp != NULL) { printf("%d ", ptemp->data); ptemp = ptemp->pNext; } printf("\n");}void modify(int data, int newdata){ struct Node* ptemp = pHead; if (ptemp == NULL) { puts("fail"); return; } while (ptemp->data != data&&ptemp != NULL) { ptemp = ptemp->pNext; } if (ptemp->data == data) ptemp->data = newdata; if (ptemp == NULL) puts("fail");}int Delete(int data){ struct Node* ptemp = pHead; struct Node* pfront = pHead; if (ptemp == NULL) { puts("fail"); return 0; } if (ptemp->data == data) { pHead = ptemp->pNext; free(ptemp); ptemp = NULL; return 1; } while (ptemp != NULL) { if (ptemp->data == data) { pfront->pNext = ptemp->pNext; free(ptemp); ptemp = NULL; return 1; } pfront = ptemp; ptemp = ptemp->pNext; } return 0;}void main(){ modify(1,2); Delete(1); AddTail(1); AddTail(2); AddTail(4); AddHead(3); Print(); Delete(3); Print(); modify(4, 5); modify(1, 6); Print();}