本质:结构体是一种构造数据类型;
用途:把不同类型的数据组合成一个整体-------自定义数据类型。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <windows.h> // 传统链表 typedef struct Node { int data; struct Node *next; }SLIST; // 不包含 data typedef struct myNode { struct Node *next; }myNode; // 非传统链表 业务节点大小可以不一样 缺点是计算节点其他数据的偏移量复杂 typedef struct teacher { int data; char name[64]; char name2[128]; struct Node node; }teacher; // 通用链表 企业链表 typedef struct teacher { struct Node node; int data; char name[64]; char name2[128]; }teacher; void testAdv() { teacher t1, t2, t3; t1.node.next = &(t2.node); t2.node.next = &(t3.node); t3.node.next = NULL; } SLIST *Create_SList();// 创建链表 int Create_SList2(SLIST **mypHead);// 创建链表 优化 int SList_Print(SLIST *pHead);// 遍历链表 int SList_NodeInsert(SLIST *pHead, int x, int y);// 插入值 在x之前插入y int SList_NodeDel(SLIST *pHead, int y); int SList_Reverse(SLIST *pHead); int SList_Destory(SLIST *pHead); // 1、不停的malloc新节点 pM = malloc() // 2、新节点入链表 pCurrent->next = pM // 3、让新节点变成当前节点 pCurrent = pM SLIST *Create_SList() { SLIST *pHead, *pM, *pCurrent; int data = 0; // 创建头节点并初始化 pHead = (SLIST *)malloc(sizeof(SLIST)); if(NULL == pHead) { return NULL; } pHead->data = 0; pHead->next = NULL; printf("\nPlease enter your data:"); scanf("%d",&data); pCurrent = pHead; while(-1 != data) { // 创建业务节点并初始化 pM = (SLIST *)malloc(sizeof(SLIST)); if(NULL == pM) { return NULL; } pM->data = data; pM->next = NULL; // 新节点入链表 pCurrent->next = pM; // 新节点变成当前节点 pCurrent = pM;// 链表节点的尾部追加 printf("\nPlease enter your data:"); scanf("%d",&data); } return pHead; } // 函数一个入口 多个出口(return) // 指针做函数参数 int Create_SList2(SLIST **mypHead) { SLIST *pHead, *pM, *pCurrent; int data = 0; int ret = 0; // 创建头节点并初始化 pHead = (SLIST *)malloc(sizeof(SLIST)); if(NULL == pHead) { ret = -1; printf("func Create_SList2() error:%d \n",ret); goto END; } pHead->data = 0; pHead->next = NULL; printf("\nPlease enter your data:"); scanf("%d",&data); pCurrent = pHead; while(-1 != data) { // 创建业务节点并初始化 pM = (SLIST *)malloc(sizeof(SLIST)); if(NULL == pM) { ret = -2; goto END; } pM->data = data; pM->next = NULL; // 新节点入链表 pCurrent->next = pM; // 新节点变成当前节点 pCurrent = pM;// 链表节点的尾部追加 printf("\nPlease enter your data:"); scanf("%d",&data); } END: if(0 != ret) { SList_Destory(pHead); } else { *mypHead = pHead; } return ret; } int SList_Print(SLIST *pHead) { SLIST *ptmp = NULL; if(NULL == pHead) { return -1; } ptmp = pHead->next; printf("\nbegin\t"); while(ptmp) { printf("%d ",ptmp->data); ptmp = ptmp->next; } printf("\tend"); return 0; } // 链表是单向的,当前节点的位置保存在前驱节点的NEXT中 int SList_NodeInsert(SLIST *pHead, int x, int y) { SLIST *pM, *pCurrent, *pPre; int data; // 创建新的节点pM pM = (SLIST *)malloc(sizeof(SLIST)); if(NULL == pM) { return -1; } pM->next = NULL; pM->data = y; //遍历链表 pPre = pHead; pCurrent = pHead->next; while(pCurrent) { if(pCurrent->data == x) { break; } pPre = pCurrent; pCurrent = pCurrent->next; } // 让新节点链接后续链表 pM->next = pPre->next; // 让前驱节点链接新节点 pPre->next = pM; return 0; } int SList_NodeDel(SLIST *pHead, int y) { SLIST *pCurrent, *pPre; // 初始化状态 pPre = pHead; pCurrent = pHead->next; // 遍历链表 while(NULL != pCurrent) { if(pCurrent->data == y) { break; } pPre = pCurrent; pCurrent = pCurrent->next; } // 删除操作 if(NULL == pCurrent) { printf("Not found %d",y); return -1; } pPre->next = pCurrent->next; if(NULL != pCurrent) { free(pCurrent); } return 0; } int SList_Destory(SLIST *pHead) { SLIST *tmp = NULL; if(NULL == pHead) { return -1; } while(pHead != NULL) { tmp = pHead->next;// 缓存头节点 free(pHead); pHead = tmp; } return 0; } int SList_Reverse(SLIST *pHead) { SLIST *p = NULL;// 前驱指针 SLIST *q = NULL;// 当前指针 SLIST *t = NULL;// 缓存的一个节点 if(NULL == pHead || NULL == pHead->next || NULL == pHead->next->next) { return 0; } // 前驱节点 // p = pHead; // q = pHead->next; p = pHead->next; q = pHead->next->next; // 一个一个节点的逆置 while(q) { t = q->next; // 缓冲节点 q->next = p;// 逆置 p = q;// 让p下移一个节点 q = t; } // 头节点变成尾部节点后置为NULL pHead->next->next = NULL; pHead->next = p; return 0; } int main() { SLIST *pHead = NULL; int ret = 0; // 创建链表并打印新链表 pHead = Create_SList(); ret = SList_Print(pHead); // 插入节点并打印新链表 ret = SList_NodeInsert(pHead, 20, 19); ret = SList_Print(pHead); // 删除节点并打印新链表 ret = SList_NodeDel(pHead, 19); ret = SList_Print(pHead); // 逆置链表节点并打印 ret = SList_Reverse(pHead); ret = SList_Print(pHead); // 销毁链表 ret = SList_Destory(pHead); system("pause"); return 0; }