博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C语言初级链表(之有头节点的单向链表)
阅读量:6224 次
发布时间:2019-06-21

本文共 5390 字,大约阅读时间需要 17 分钟。

1 #define  _CRT_SECURE_NO_WARNINGS  2 #include 
3 #include
4 5 6 typedef struct Node 7 { 8 int data; 9 struct Node *next; 10 }SLIST; 11 12 13 //创建链表 14 SLIST *Slist_create() 15 { 16 SLIST *pHead, *pM, *pCur; //申请链表的辅助指针变量 17 int data; //数据域的接收 18 19 //创建头节点并初始化 20 pHead = (SLIST *)malloc(sizeof(SLIST)); 21 if (NULL == pHead) 22 return NULL; 23 pHead->data = 0; 24 pHead->next = NULL; 25 26 //提示输入内容 27 printf("plz input the data \n"); 28 scanf("%d", &data); 29 30 //对当前结点进行定位 31 pCur = pHead; 32 33 //循环创建业务节点 34 while (data != -1) 35 { 36 //创建业务节点实际操作、然后初始化 37 pM = ((SLIST *)malloc(sizeof(SLIST))); 38 if (NULL == pM) 39 return NULL; 40 pM->data = data; 41 pM->next = NULL; 42 43 //业务节点入链表 44 pCur->next = pM; 45 46 //当前节点下移 47 pCur = pM; 48 49 //提示输入内容 50 printf("plz input the data \n"); 51 scanf("%d", &data); 52 53 } 54 55 return pHead; 56 } 57 58 59 //打印链表 60 int Slist_printf(SLIST *pHead) //形参接收头节点地址 61 { 62 SLIST *tap = NULL; //创建临时指针变量 63 if (NULL == pHead) 64 return -1; 65 67 //临时指针变量初始化 :第一个节点 68 tap = pHead->next; 69 70 printf("\nSTART\n"); 71 while (tap) 72 { 73 //打印当前结点数据域的内容 74 printf("%d ", tap->data); 75 76 //临时指针变量下移 77 tap = tap->next; 78 } 79 printf("END\n"); 80 return 0; 81 } 82 83 //在链表中某一位置插入元素 84 int Slist_NodeInsert(SLIST *pHead, int x, int y) 85 { 86 //创建辅助指针变量 87 SLIST *pPre, *pCur, *pM; 88 89 //前驱结点初始化 90 pPre = pHead; 91 //当前结点初始化 92 pCur = pHead->next; 93 //创建插入节点 94 pM = (SLIST *)malloc(sizeof(SLIST)); 95 //插入节点初始化 96 pM->next = NULL; 97 //数据域为要插入的值 98 pM->data = y; 99 //遍历链表100 while (pCur)101 {102 //判断元素节点,如果是跳出循环103 if (pCur->data == x)104 break;105 //指针下移106 pPre = pCur;107 pCur = pCur->next;108 109 }110 //插入节点入链表:分为两种情况,①找到要插入的节点插入在当前位置②未找到要插入的节点,插入在链表尾部111 pM->next = pPre->next;112 pPre->next = pM;113 return 0;114 }115 116 //删除链表节点117 int Slist_NodeDel(SLIST *pHead, int y)118 {119 //创建辅助指针变量120 SLIST *pPre, *pCur;121 //指针变量初始化122 pPre = pHead;123 pCur = pHead->next;124 125 //遍历链表126 while (pCur)127 {128 //判断是否找到要删除的链表节点;如果是则跳出循环129 if (pCur->data == y)130 break;131 132 //指针下移133 pPre = pCur;134 pCur = pCur->next;135 }136 //判断是否找到要删除的链表节点:未找到137 if (pCur == NULL)138 {139 printf("未找到要删除的节点\n");140 return -1;141 }142 //找到要删除的链表节点143 pPre->next = pCur->next;144 //这段判断语句的作用是:判断链表是否存在145 if (pPre == NULL)146 free(pCur); //释放当前节点内存(即要删除节点的内存)147 return 0;148 }149 150 //链表逆置151 int Slist_Reverse(SLIST *pHead)152 {153 //创建指针变量154 SLIST *pPre, *pCur, *tap;155 //判断是否需要逆置:(当链表元素>=2时才可以逆置)156 if (pHead == NULL || pHead->next == NULL || pHead->next->next == NULL)157 return -1;158 //初始化指针变量159 pPre = pHead->next;160 pCur = pHead->next->next;161 //遍历链表162 while (pCur)163 {164 //缓存当前结点的指针域165 tap = pCur->next;166 //对当前结点的指针域重新赋值为前驱结点; 即逆置167 pCur->next = pPre; //(这里有做错:写成pCur->next = pPre-next)168 //指针下移169 pPre = pCur;170 pCur = tap;171 }172 173 //对头节点和第一个元素的指针域进行处理174 pHead->next->next = NULL;175 pHead->next = pPre;176 177 return 0;178 }179 180 //销毁链表181 int Slist_Destory(SLIST *pHead)182 {183 //创建辅助指针变量184 SLIST *tap;185 186 //判断链表是否存在187 if (pHead == NULL)188 return -1;189 //遍历链表190 while (pHead)191 {192 //缓存当前节点的指针域193 tap = pHead->next;194 //释放当前结点195 free(pHead);196 //指针下移197 pHead = tap;198 }199 return 0;200 }201 202 203 int main(void)204 {205 int ret = 0;206 SLIST *pHead = NULL;207 208 //创建链表209 pHead = Slist_create();210 ret = Slist_printf(pHead);211 //给链表中插入元素212 ret = Slist_NodeInsert(pHead, 20, 19);213 ret = Slist_printf(pHead);214 //删除链表中某个元素215 ret = Slist_NodeDel(pHead, 19);216 ret = Slist_printf(pHead);217 //重置链表中的元素218 ret = Slist_Reverse(pHead);219 ret = Slist_printf(pHead);220 //销毁链表221 ret = Slist_Destory(pHead);222 223 return 0;224 225 }

 

  

1.结构体的基本特点:(结构体中可以嵌套一个别的结构体;  ..........可以嵌套一个别的结构体指针)

          (结构体中不可以嵌套一个自身类型的结构体(原因:确定不了结构体的内存大小);  

             ..........可以嵌套一个指向自身类型的指针(原因:不同类型的指针在同一操作平台下所占内存相同,有确定值)

2.数据类型的本质:固定大小的内存块别名。

3.链表的基础特点:(结构体; 两个域:数据域、指针域;  引用自身的结构体;  特点:非线性存储)

4.链表编程关键两点:

    1)指针指向谁,就把谁的地址赋给指针

    2)辅助指针变量&操作逻辑的关系(辅助指针:pHead(头节点)  pPre(前驱结点)  pCur(当前结点)  pM(业务节点))

 =========================================================

此段代码刚开始是: 两个文件.C 和 一个.h文件,传代码由于不方便放到一个.C文件。

编写这段代码时,最难理解的是辅助节点的建立和移动。 编写错误的:167  pCur->next = pPre;(正确写法)
        pCur->next = pPre->next;(错误写法:这种写法造成对第二元素的循环打印,死循环。)       
      63   if (NULL == pHead);(正确写法)           if (NULL == tap); (错误写法:这种写法造成程序崩溃;)。
 

转载于:https://www.cnblogs.com/yyx1-1/p/5641246.html

你可能感兴趣的文章
linux环境下安装sphinx中文支持分词搜索(coreseek+mmseg)
查看>>
用户IP地址的三个属性的区别(HTTP_X_FORWARDED_FOR,HTTP_VIA,REM_addr
查看>>
编写高质量代码:改善Java程序的151个建议(第1章:JAVA开发中通用的方法和准则___建议11~15)...
查看>>
华为OJ平台试题 ——数组:整形数组合并
查看>>
ORA-01410: 无效的 ROWID
查看>>
【Spark】Spark Streaming + Kafka direct 的 offset 存入Zookeeper并重用
查看>>
golang web开发获取get、post、cookie参数
查看>>
一个JAVA程序员经常访问的网站
查看>>
漫画:鉴权与安全访问控制的技术血脉
查看>>
C# 3.0入门系列-目录导航
查看>>
CrashMe for windbg
查看>>
使用Microsoft Web Application Stress Tool对web进行压力测试
查看>>
重装上了Fedora8自带的MySQL5.0.45,再试,告捷!!
查看>>
为一张PCI卡打通经络的过程
查看>>
mahout算法源码分析之Itembased Collaborative Filtering(三)RowSimilarityJob验证
查看>>
179. Largest Number
查看>>
Git命令行大全
查看>>
Node.js 4493图片批量下载爬虫1.00
查看>>
其实人缺乏对数据的真实分析能力,只知道数据展现和推演
查看>>
连接H3C交换机的Console口连不上
查看>>