本质:结构体是一种构造数据类型;
用途:把不同类型的数据组合成一个整体-------自定义数据类型。
#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;
}