直接插入全部代码:(reverseLinklist函数是逆置操作)

#include <stdio.h>
#include <stdlib.h>
#include <assert.h> typedef int LDataType;
typedef struct Linklist{
LDataType data;
struct Linklist *next;
}Linklist,*pLinklist; pLinklist BuyNewNode(LDataType data); //动态生成新结点
void InitLinklist(pLinklist *pL); //初始化单链表
void PushBackLinklist(pLinklist *pL,LDataType data); //尾插
void PushFrontLinklist(pLinklist *pL,LDataType data); //头插
void PopBackLinklist(pLinklist* pL); //尾删
void PopFrontLinklist(pLinklist *pL); //头删
void PrintLinklist(Linklist *pL); //打印单链表
pLinklist FindLinklist(pLinklist *pL,LDataType data); //查找指定元素,返回元素位置
void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data); //指定位置插入
void RemoveLinklist(pLinklist* pL,LDataType data); //删除第一个指定元素
void RemoveAllLinklist(pLinklist *pL,LDataType data); //删除所有指定元素
int IsEmptyLinklist(pLinklist pL); //判断链表是否为空
void DestoryLinklist(pLinklist *pL); //销毁单链表
pLinklist reverseLinklist(pLinklist *pL); int main(void){
Linklist *first = NULL;
InitLinklist(&first);
PushBackLinklist(&first,5);
PushBackLinklist(&first,4);
PushBackLinklist(&first,3);
PushBackLinklist(&first,2);
PushBackLinklist(&first,1);
PushBackLinklist(&first,0);
PushFrontLinklist(&first,6);
first = reverseLinklist(&first);
PushFrontLinklist(&first,-1);
PrintLinklist(first);
} pLinklist BuyNewNode(LDataType data){
pLinklist NewNode = (pLinklist)malloc(sizeof(Linklist));
if (NewNode == NULL){
printf("动态开辟内存空间失败\n");
return NULL;
}
NewNode->data = data;
NewNode->next = NULL;
return NewNode;
}
void InitLinklist(pLinklist *pL){
assert(pL != NULL); //初始化操作
(*pL) = NULL;
}
void PushBackLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //尾插一个数据域为data的结点
pLinklist NewNode = BuyNewNode(data);
if(*pL == NULL){
*pL = NewNode;
return ;
}
pLinklist cur = *pL;
while(cur->next){
cur = cur->next;
}
cur->next = NewNode;
}
void PushFrontLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //头插一个数据域为data的结点
pLinklist NewNode = BuyNewNode(data);
if(*pL == NULL){
*pL = NewNode;
return ;
}
NewNode->next = *pL;
*pL = NewNode;
}
int IsEmptyLinklist(pLinklist pL){
return (pL == NULL); //判断无头单链表是否为空
}
void PopBackLinklist(pLinklist *pL){
assert(pL != NULL); //尾删
if(IsEmptyLinklist(*pL)){
puts("链表为空,删除失败");
return ;
}
pLinklist cur = *pL;
pLinklist pre;
if(cur->next == NULL){
//只有一个结点
*pL = NULL;
free(cur);
cur = NULL;
return ;
}
while(cur->next){
pre = cur;
cur = cur->next;
}
pre->next = NULL;
free(cur);
cur = NULL;
}
void PopFrontLinklist(pLinklist *pL){
assert(pL != NULL); //头删,既是删除第一个结点
if(*pL == NULL){
printf(" 链表为空,删除失败");
return ;
}
pLinklist cur = *pL;
*pL = cur->next;
free(cur);
cur = NULL;
}
pLinklist FindLinklist(pLinklist *pL,LDataType data){
assert( pL != NULL); //找到第一个数据为data的结点
pLinklist cur = *pL;
while(cur){
if (cur->data == data){
return cur;
}
cur = cur->next;
}
return NULL;
}
void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data){
assert(pL != NULL); //xiangp结点之前插入一个数据为data的元素
pLinklist NewNode = BuyNewNode(data);
pLinklist cur = *pL;
while(cur->next != p){
cur = cur->next;
}
NewNode->next = p;
cur->next = NewNode;
}
void RemoveLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //删除第一个数据域为data的结点
pLinklist cur = NULL;
pLinklist p = *pL;
pLinklist pre = NULL;
cur = FindLinklist(pL,data);
if (cur == NULL){
printf("未找到要删除的元素");
return ;
}
if (*pL == cur){
//位于第一个结点
*pL = cur->next;
free(cur);
cur = NULL;
return ;
}
while(p != cur){
pre = p;
p = p->next;
}
pre->next = cur->next;
free(cur);
cur = NULL;
}
void RemoveAllLinklist(pLinklist *pL,LDataType data){
assert(pL != NULL); //删除每一个数据域都是data的结点
pLinklist cur = NULL;
pLinklist p = *pL;
pLinklist pre = *pL;
while(p){
if (p->data == data && (*pL) == p){
//第一个结点是
pre = p;
p = p->next;
*pL = p;
free(pre);
pre = NULL;
}
else if(p->data == data){
//后续结点是
cur = p;
p = p->next;
pre->next = p;
free(cur);
cur = NULL;
}
else{
//此结点不是
pre = p;
p = p->next;
}
}
}
void PrintLinklist(Linklist *pL){
pLinklist cur = pL; //打印链表
while(cur){
printf("%d--->",cur->data);
cur = cur->next;
}
printf("NULL\n");
}
void DestoryLinklist(pLinklist *pL){
assert(pL != NULL); //摧毁链表
pLinklist cur = *pL;
pLinklist pre = NULL;
if (*pL == NULL){
printf("链表为空");
return ;
}
if (cur->next = NULL){
*pL = NULL;
free(cur);
cur = NULL;
return ;
}
while(cur){
pre = cur;
cur = cur->next;
free(pre);
pre = NULL;
}
}
pLinklist reverseLinklist(pLinklist *pL){
if((*pL) == NULL || pL == NULL){
return NULL;
}
if((*pL)->next == NULL){
return *pL;
}
Linklist *p = *pL;
Linklist *q = (*pL)->next;
Linklist *r = *pL;
while(q->next != NULL){
r = q->next;
q->next = p;
p = q;
q = r;
r = r->next;
}
q->next = p;
(*pL)->next = NULL;
*pL = q;
return *pL;
}

第一步就是判断这个单链表是否为空,因为我用了二级指针,因此要看链表为空的同时还要看pL是否指向有问题。

然后看几个元素,如果只有一个元素的话,直接返回就行了,剩下的难点是如何解决超过一个元素的链表;

注意到我用了p,q,r;三个指向结点的指针,p是存前一个元素,q是实现逆置的指针,通过它来指向前面那一个结点,r是后面的指针,其存在的意义是为了让q有后续,因为q指向其他地方后,无法通过p = p->next进行传递。下面是图示。

我感觉应该听得懂。(图中最后一步没有在图中把原来头指针指向结点的next域改为NULL,看图请注意!!!

逆置单链表(基于c语言)的更多相关文章

  1. 单链表(C语言实现)

    链表结构: SList.h //-------------------------------------------------------------------------- /* **功能:应 ...

  2. 无头结点的单链表(C语言)

    1.单链表: 在顺序表中,用一组地址连续的存储单元来一次存放线性表的结点,因此结点的逻辑顺序与物理顺序是一致的.但链表却不同,链表是用一组任意的存储单元来存放 线性表的结点,这组存储单元可以是连续的, ...

  3. 单链表(c语言实现)贼详细

    直接上代码吧 #include<stdio.h> #include<malloc.h> /* 单链表特点: 它是一种动态的储存结构,链表中每个节点占用的储存空间不是预先分配的, ...

  4. C语言版本:单链表的实现(优化版本)

    未优化版本:http://www.cnblogs.com/duwenxing/p/7569376.html slist.h #ifndef __SLIST_H__ #define __SLIST_H_ ...

  5. C语言版本:单链表的实现

    slist.h #ifndef __SLIST_H__ #define __SLIST_H__ #include<cstdio> #include<malloc.h> #inc ...

  6. 如何使用C++实现单链表

    线性表--链表 为什么假期也在发文章 //TODO NullGirlfrindException 请忽略以上两行无聊的事实...... 如何弥补顺序表的不足之处? 第一次学习线性表一定会马上接触到一种 ...

  7. Java带头节点单链表的增删合并以及是否有环

    带头节点单链表 1.优势: 1)当链表为空时,指针指向头结点,不会发生null指针异常 2)方便特殊操作(删除第一个有效节点或者插入一个节点在表头) 3)单链表加上头结点之后,无论单链表是否为空,头指 ...

  8. 数据结构C语言实现系列——线性表(线性表链接存储(单链表))

    #include <stdio.h>#include <stdlib.h>#define NN 12#define MM 20typedef int elemType ;/** ...

  9. C语言单链表实现19个功能完全详解

    谢谢Lee.Kevin分享了这篇文章 最近在复习数据结构,想把数据结构里面涉及的都自己实现一下,完全是用C语言实现的. 自己编写的不是很好,大家可以参考,有错误希望帮忙指正,现在正处于编写阶段,一共将 ...

随机推荐

  1. 关于synchronized(this)中this指的是什么意思

    public class SynchronizedDEmo { public static void main(String[] args) { TestThread tt = new TestThr ...

  2. postman python疑难

    例子1:postman请求时会将默认的headers的content-type替换成Content-Type,而直接使用python的request则不行,服务器端就会接收到错误的Content-Ty ...

  3. 第11、12章等待方法和alter框处理

    11.等待方法 time sleep webdriver implicitly_wait() 设置浏览器等待时间 WebDriverWait 等待条件满足或超时后退出   12.alter对话框处理 ...

  4. PHP宝典面试笔试题目

    PHP宝典面试笔试题目 来自<PHP程序员面试笔试宝典>,涵盖了近三年了各大型企业常考的PHP面试题,针对面试题提取出来各种面试知识也涵盖在了本书. PHP题目 [真题68] (    ) ...

  5. 《PHP程序员面试笔试宝典》——如何处理与面试官持不同观点这个问题?

    如何巧妙地回答面试官的问题? 本文摘自<PHP程序员面试笔试宝典> 在面试的过程中,求职者所持有的观点不可能与面试官一模一样,在对某个问题的看法上,很有可能两个人相去甚远.当与面试官持不同 ...

  6. 【lwip】lwip源码基础

    目录 前言 概念&作用 网络接口 概念引入 总结 lwip netif 结构体 链接 字段分析 网卡链表 网络 IP 接收数据函数 发送数据函数 ARP 模块调用的发送函数 出口回调函数 用户 ...

  7. 技术管理进阶——谁能成为Leader,大Leader该做什么

    原创不易,求分享.求一键三连 两个故事 谁能成为Leader 之前接手了一块产品业务线,于是与原Leader说了下分工,大概意思是: 我是过来学习的,也能给团队带来更多的资源,团队内的工作你继续管理, ...

  8. 前端提升生产力系列三(vant3 vue3 移动端H5下拉刷新,上拉加载组件的封装)

    | 在日常的移动端开发中,经常会遇到列表的展示,以及数据量变多的情况下还会有上拉和下拉的操作.进入新公司后发现移动端好多列表,但是在看代码的时候发现,每个列表都是单独的代码,没有任何的封装,都是通过v ...

  9. 目前市面上报表软件下载排名的TOP5

    目前,大部分的工作仍然离不开表格,而且工作表格的呈现更酷.效率要求更高.可以简化复杂的操作,大大提高工作效率.在企业管理中,报表可以以图表等简洁的方式向用户显示数据,从而提高工作效率.许多哦公司紧跟信 ...

  10. 【windows安全性 之访问控制】 访问控制 详细解说

    windows的安全性的两个基本支柱是身份验证(登入)和授权(访问控制). 身份验证是标识用户的过程 ,授权在验证了所标识用户是否可以访问特定资源之后进行. 相关的命名空间和类: System.Sec ...