|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 moc 于 2018-9-23 16:10 编辑
1、链表基本概念
链表:是一种物理存储单元上非连续的存储结构,由一系列结点(链表中每一个元素称为结点)组成,结点动态生成,结点与结点之间通过指针链接。
每个结点包括两个部分:一部分是存储数据元素的数据域,另一部分是存储下一个结点地址的指针域。
链表的特点:
1 链表是一种常用的数据结构,它通过指针将一些列数据结点,连接成一个数据链。相对于数组,链表具有更好的动态性。
2 数据域用来存储数据,指针域用于建立与下一个结点的联系。
3 建立链表时无需预先知道数据总量的,可以随机的分配空间,可以高效的在链表中的任意位置实时插入或删除数据。
4 链表的开销,主要是访问顺序性和组织链的空间损失。
约定:
•头结点、当前结点、前趋结点、后继结点 新建结点
•pHead、pCurrent、 pPrior、 pNext、 pMalloc
链表编程关键点:
1、指针指向谁,就把谁的地址赋给指针
2、辅助指针变量&操作逻辑的关系
2、静态链表
手工依次为各结点建立指向关系,不能动态增加或减少结点,应用范围小。
- struct AdvTeacher
- {
- char name[64];
- int age;
- struct AdvTeacher *next;
- };
- struct AdvTeacher t1, t2, t3;
- struct AdvTeacher *p;
- t1.age = 10;
- t2.age = 20;
- t3.age = 30;
- t1.next = &t2; //建立结点之间的指向
- t2.next = &t3;
- t3.next = NULL;
- //遍历链表
- while (p)
- {
- printf("age:%d\n", p->age);
- p = p->next;
- }
复制代码
3、带头结点的单项链表
头结点作为链表的开始,第一个结点为业务结点的开始,在进行接口的封装和设计时,链表的对外属性只有指向头结点的指针,其余的操作通过封装好的函数进行。
1.创建链表
创建链表的头结点,需要在函数内申请内存空间,返回内存空间的首地址(指针函数,二级指针做输出)。
2.循环打印链表
通过辅助指针记录当前位置,在链表中循环。
3. 指定结点前插入结点,如果没找到指定结点插到最后
建立要插入的结点,建立两个辅助指针变量,一个指向当前结点,一个指向当前结点的前一个结点,循环每个结点,如果找到指定结点break,最后新结点链到当前结点,前一个结点链到新结点。
4.删除指定的结点
循环每个结点,找到指定结点后删除并返回。
5.链表的逆置操作
1.当链表只有头结点或只有一个业务结点不需要逆置,直接返回即可。
2.准备环境:p保存第一个结点,q保存第二个结点
3.从第二个结点开始操作,先缓存q的下一个结点,然后逆置(让第二个结点指向第一个结点),然后p,q各向后移一个对第三个结点做同样操作,知道q的指向NULL.
4.最后把原先的第一个结点指向NULL,头结点指向p即可。
示例代码:
- #include "stdlib.h"
- #include "stdio.h"
- #include "string.h"
- #define _CRT_SECURE_NO_WARNINGS
- typedef struct Node
- {
- int data;
- struct Node *pNext;
- }SLIST;
- SLIST *Creat_SList()
- {
- int data = 0;
- // 1建立头结点并初始化
- SLIST *pHead = NULL, *pm = NULL, *pCur = NULL;
- pHead = (SLIST*)malloc(sizeof(SLIST));
- if (pHead == NULL)
- {
- return -1;
- }
- pHead->data = 0;
- pHead->pNext = NULL;
- pCur = pHead;
- // 2循环建立结点,结点中的数据域由键盘输入
- printf("\n Please enter the data of node(-1:quit):");
- scanf("%d", &data);
- while (data != -1)
- {
- // 不断的malloc新结点, 并为数据域赋值
- pm = (SLIST*)malloc(sizeof(SLIST));
- if (pm == NULL)
- {
- SList_Destory(pHead);
- return NULL;
- }
- pm->data = data;
- pm->pNext = NULL;
- // 新结点加入链表
- pCur->pNext = pm;
- pCur = pm;
- printf("\n Please enter the data of node(-1:quit):");
- scanf("%d", &data);
- }
- return pHead;2.
- }
- //打印链表中的每一个值
- int SList_Print(SLIST *pHead)
- {
- SLIST *pCur = NULL;
- if (pHead == NULL)
- {
- return -1;
- }
- // 准配环境
- pCur = pHead->pNext;
- printf("\nBegin ");
- while (pCur)
- {
- printf("%d ", pCur->data);
- pCur = pCur->pNext;
- }
- printf("End \n ");
- }
- // 在结点数值为x的前面插入y,如果没找到加到最后
- int SList_NodeInsert(SLIST *pHead, int x, int y)
- {
- SLIST *pCur = pHead, *pPre = NULL, *pTemp = NULL;
- if (pHead == NULL)
- {
- return -1;
- }
- pTemp = (SLIST*)malloc(sizeof(SLIST));
- if (pTemp == NULL)
- {
- return -2;
- }
- pTemp->data = y;
- while (pCur) // 查找值为x结点的前一个结点
- {
- if (pCur->data == x)
- {
- break;
- }
- pPre = pCur;
- pCur = pCur->pNext;
- }
- // 新结点链接到后继结点
- pTemp->pNext = pPre->pNext;
- // 让前驱结点链接到pTemp
- pPre->pNext = pTemp;
- return 0;
- }
- // 删除值为y的结点,如果不存在则打印删除结点不存在
- int SList_NodeDel(SLIST *pHead, int y)
- {
- SLIST *pCur = pHead, *pPre = NULL;
- if (pHead == NULL)
- {
- return -1;
- }
- while (pCur)
- {
- if (pCur->data == y)
- {
- pPre->pNext = pCur->pNext;
- free(pCur);
- return 0;
- }
- pPre = pCur;
- pCur = pCur->pNext;
- }
- printf("值为%d结点不存在!\n", y);
- }
- // 链表逆置操作 //从第二个结点开始逆置
- int SList_revse(SLIST *pHead)
- {
- SLIST *p = NULL, *q = NULL, *t = NULL;
- if (pHead == NULL)
- {
- return -1;
- }
- if (pHead->pNext == NULL || pHead->pNext->pNext == NULL)
- {
- return 0;
- }
- // 准备环境
- p = pHead->pNext;
- q = pHead->pNext->pNext;
- while (q != NULL)
- {
- //1. 逆置之前做个缓存
- t = q->pNext;
- //2.开始逆置
- q->pNext = p;
- //3.p,q分别后移
- p = q;
- q = t;
- }
- // 扫尾工作
- pHead->pNext->pNext = NULL;
- pHead->pNext = p;
- return 0;
- }
- // 销毁整个链表
- int SList_Destory(SLIST *pHead)
- {
- SLIST *pCur = pHead, *pTemp = NULL;
- if (pHead == NULL)
- {
- return -1;
- }
- while (pCur)
- {
- // 缓存后继结点
- pTemp = pCur->pNext;
- // 删除当前结点
- free(pCur);
- // 当前结点下移
- pCur = pTemp;
- }
- return 0;
- }
- void main()
- {
- SLIST *pHead = NULL;
- pHead = Creat_SList();
- SList_Print(pHead);
- SList_NodeInsert(pHead, 20, 19);
- SList_Print(pHead);
- SList_NodeDel(pHead, 20);
- SList_Print(pHead);
- SList_revse(pHead);
- SList_Print(pHead);
- SList_Destory(pHead);
- system("pause");
- }
复制代码
|
|