| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
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");
 
 - }
 
  复制代码 
 
 |   
 
 
 
 |