川沙网站建设,洛阳建站公司效果,南阳专业做网站公司,梵克雅宝官网中文官网结构体与链表
在 C 语言中#xff0c;结构体是一种用户自定义的数据类型#xff0c;它可以把不同类型的数据组合在一起#xff0c;形成一个整体。
struct Node {
int data;
struct Node *next;
};
这段代码定义了一个叫 Node 的结构体#xff0c;它有两个成员#xff1a;
…结构体与链表在 C 语言中结构体是一种用户自定义的数据类型它可以把不同类型的数据组合在一起形成一个整体。struct Node {int data;struct Node *next;};这段代码定义了一个叫 Node 的结构体它有两个成员int data用来存储实际的数据比如整数。struct Node *next是一个指针指向下一个 Node 类型的结构体。结构体的内存布局当我们定义了一个 struct Node编译器会为它分配一块连续的内存空间大小等于所有成员占用空间之和。假设 int 占 4 字节指针也占 8 字节64位系统那么每个 Node 节点总共占 12 字节或更多因对齐规则可能增加。如何创建链表节点静态创建struct Node node1;struct Node node2;struct Node node3;struct Node node4;node1.data 1;node2.data 2;node3.data 3;node4.data 4;node1.next node2;node2.next node3;node3.next node4;这里是直接在栈上声明变量四个 Node 对象都存放在程序的栈区。每个节点有名字如 node1可以通过名字访问。使用 node2 获取 node2 的地址赋值给 node1.next就建立了连接。动态创建struct Node *node1 (struct Node *)malloc(sizeof(struct Node));struct Node *node2 (struct Node *)malloc(sizeof(struct Node));// … 其他节点使用 malloc() 在堆heap 上申请内存。返回的是一个指向该内存的指针所以我们必须用指针接收。每个节点都是独立申请的可以随时增删。起别名typedef struct Node {int data;struct Node *next;} Node, LinkNode, *sNode;typedef struct Node {…} Node;给 struct Node 起了个别名 Node以后可以直接写 Node 而不用写 struct Node。比如Node node1; 就等价于 struct Node node1;LinkNode 是另一个别名可以当作 Node 的别名使用用于命名一致性。*sNode 是指针类型的别名sNode 表示“指向 Node 结构体的指针”所以 sNode node4; 相当于 struct Node *node4;链接链表node1-data 1;node2-data 2;node3-data 3;node4-data 4;node1-next node2;node2-next node3;node3-next node4;node1 → node2 → node3 → node4 → NULL内存地址: 0x1000 0x2000 0x3000 0x4000±---------±---------±---------±---------| data1 | next0x2000| data2 | next0x3000| …±---------±---------±---------±---------遍历读取链表voidprintList(Node*head){for(Node*curhead;cur!NULL;curcur-next){printf(%d,cur-data);if(cur-next!NULL){printf(-);}}printf(\n);}插入/删除链表插入链表intinsertAt(Node**head,intindex,intvalue){intlengetListLen(*head);if(index0||indexlen){return-1;// 插入失败}Node*newNode(Node*)malloc(sizeof(Node));if(!newNode){return-1;}newNode-datavalue;if(index0){newNode-next*head;*headnewNode;}else{Node*prev*head;for(inti0;iindex-1;i){prevprev-next;}newNode-nextprev-next;prev-nextnewNode;}return0;}这里传参需要二维指针是因为需要修改指针指向若一维指针只是拷贝传递。删除链表:// 删除第一个值为 data 的节点voiddelList(Node**head,intdata){if(*headNULL)return;// 如果要删除的是头节点if((*head)-datadata){Node*temp*head;*head(*head)-next;free(temp);return;}Node*cur*head;while(cur-next!NULL){if(cur-next-datadata){Node*tempcur-next;cur-nextcur-next-next;free(temp);return;// 只删第一个匹配项}curcur-next;}}双向链表#includestdio.h#includestdlib.htypedefstructNode{intdata;structNode*next;structNode*prev;}Node;// 获取链表长度intgetListLen(Node*head){inti0;for(Node*curhead;cur!NULL;curcur-next){i;}returni;}intinsertAt(Node**head,intindex,intvalue){intlengetListLen(*head);if(index0||indexlen){return-1;}Node*newNode(Node*)malloc(sizeof(Node));if(!newNode){return-1;}newNode-datavalue;newNode-nextNULL;newNode-prevNULL;if(index0){newNode-next*head;if(*head!NULL){(*head)-prevnewNode;}*headnewNode;}else{Node*cur*head;for(inti0;iindex;i){curcur-next;}newNode-nextcur;newNode-prevcur-prev;cur-prev-nextnewNode;cur-prevnewNode;}return0;}// 输出链表voidprintList(Node*head){for(Node*curhead;cur!NULL;curcur-next){printf(%d,cur-data);if(cur-next!NULL){printf(-);}}printf(\n);}// 删除第一个值为 data 的节点voiddelList(Node*head,intdata){if(headNULL)return;Node*curhead;while(cur!NULL){if(cur-datadata){if(cur-prev!NULL){cur-prev-nextcur-next;}else{headcur-next;// 删除头节点}if(cur-next!NULL){cur-next-prevcur-prev;}free(cur);return;}curcur-next;}}intmain(){constintN4;intvalues[N]{10,20,30,40};Node*headNULL;Node*tailNULL;// 使用头插法for(inti0;iN;i){Node*newNode(Node*)malloc(sizeof(Node));if(!newNode){return-1;}newNode-datavalues[i];newNode-nextNULL;newNode-prevtail;if(headNULL){headtailnewNode;}else{;tailnewNode;}}intlengetListLen(head);printf(链表长度: %d\n,len);// 插入printf(index2 99);if(insertAt(head,2,99)0){printf(插入后: );printList(head);}// 删除printf(请输入要删除的数据: );intdata;scanf(%d,data);delList(head,data);printf(删除后: );printList(head);return0;}