数据结构——不带头结点的单链表的基本操作

2023-05-16

数据结构——不带头节点的单链表的基本操作

结构体的创建:

typedef struct SListNode
{
	ElemType data;
	struct SListNode *next;
}SListNode;

typedef SListNode* SList;

单链表的基本操作:

初始化:

void SListInit(SList *phead)//初始化
{
	assert(phead != NULL); //因为phead是外部实参的地址,所以地址是一定存在的,不可能为空
	                       //如果为NULL的话一定是出错误了,所以用assert断言来提示
	
	*phead = NULL;         //在变量声明的时候,如果没有确切的地址可以赋值,
						   //为指针变量赋一个 NULL 值是一个良好的编程习惯。
	                       //赋为 NULL 值的指针被称为空指针
}
void SListPushBack(SList *phead, ElemType x)//尾插法
{
	assert(phead);
	SList s = (SList)malloc(sizeof(SListNode));
	assert(s!= NULL);
	s->data = x;
	s->next = NULL;
	SList p = *phead;
	//连接
	if (p == NULL)
	{
		*phead = s;
	}
	else
	{
		while (p->next != NULL)
		{
			p = p->next;
		}
		p->next = s;
	}
}
void SListPushFront(SList *phead, ElemType x)    //头插法
{
	assert(phead!=NULL);
	SList s = (SList)malloc(sizeof(SListNode));
	s->data = x;
	s->next = NULL;
	//连接
	s->next = *phead;     //当无节点时也不会影响,因为初始化中*phead=NULL;
	*phead = s;
}
void SListPopBack(SList *phead)    //尾部删除 分为三种情况:0个,1个,多个节点
{
	assert(phead != NULL);
	SList p = *phead;
	SList prev = NULL;
	if (*phead == NULL)    //0个节点
	{
		printf("链表为空,无节点可删!");
		return;
	}

	else if ((*phead)->next == NULL)    //1个节点
	{
		free(*phead);
		*phead = NULL;
		printf("删除成功!");
		return;
	}

	else{
		while(p->next != NULL)    //多个节点
		{
			prev = p;
			p = p->next;
		}
		
		free(p);
		prev->next = NULL;
		printf("删除成功!");
	}	
}

头部删除

{
void SListPopFront(SList *phead)//头部删除
{
	assert(phead != NULL);
	SList p = *phead;
	if (*phead == NULL)    //0个节点
	{
		printf("链表为空,无节点可删!");
		return;
	}
	else
	{
		*phead = p->next;
		free(p);
	}

}

显示

void SListShow(SList phead)//显示
{
	//assert(phead != NULL);
	SListNode *p = phead;
	while (p != NULL)
	{
		printf("%d->", p->data);
		p = p->next;
	}
	printf("Over.\n");
}
size_t SListLength(SList phead)//单链表长度
{
	//assert(phead != NULL);
	size_t size = 0;
	SListNode *p = phead;
	while (p != NULL)
	{
		size++;
		p = p->next;
	}
	return size;
}
SListNode* SListFind(SList phead, ElemType key)//按值寻找
{
	SListNode *p = phead;
	while (p != NULL && p->data != key)
		p = p->next;
	return p;
}
void SListEraseByVal(SList *phead, ElemType key)//按值删除;
{
	assert(phead != NULL);
	SList p = SListFind(*phead, key);
	if (p == NULL)
	{
		printf("不存在该值!");
		return;
	}

	SList prev = *phead;
	if (prev == p)   //
	{
		free(p);
		*phead = NULL;
	}
	else
	{
		while (prev->next != p)
			prev = prev->next;
		prev->next = p->next;
		free(p);
	}
}
void SListInsertByVal(SList *phead, ElemType key)//按值插入
{
	assert(phead != NULL);
	SList p = *phead;
	SList prev = NULL;
	if (*phead == NULL)
	{
		SListPushFront(phead, key);
	}
	else
	{
		while (key > p->data)
		{
			prev = p;
			p = p->next;
		}
		SList s = (SList)malloc(sizeof(SListNode));
		s->data = key;
		s->next = prev->next;
		prev->next = s;
		printf("添加成功!");
	}
}
void Sort(SList *phead) //按值排序2
{
	assert(phead != NULL);
	if (SListLength(*phead) <= 1)
	{
		printf("该链表长度为%d,无需排序!", SListLength(*phead));
		return;
	}
	else
	{
		SList p = *phead;
		SList q = p->next;
		p->next = NULL;
		while (q != NULL)
		{
			SList tmp = *phead;           //在while循环中定义保证每次tmp指向头结点
			p = q;
			q = q->next;
			if ((p->data > (*phead)->data)) //与头进行比较决定插入位置前后
			{
				while (tmp->next != NULL && (p->data) > (tmp->next)->data)  //后插,找出插入位置的前驱,保证有序
				{ //注意:先判断tmp是否为空,否则比较时候会出错
					tmp = tmp->next;
				}
				p->next = tmp->next;
				tmp->next = p;
			}
			else                          //前插
			{
				p->next = *phead;
				*phead = p;
			}
			tmp = *phead;
		}
	}
}
void SListSort(SList *phead)//按值排序
{
	assert(phead != NULL);
	if (SListLength(*phead) <= 1)
	{
		printf("该链表长度为%d,无需排序!", SListLength(*phead));
		return;
	}
	else
	{
		SList tmp = *phead;
		SList prev = NULL;
		SList p = *phead;
		SList q = p->next;
		p->next = NULL;
		while (q != NULL)
		{
			p = q;
			q = q->next;
			while (tmp != NULL&&p->data > tmp->data)
			{
				prev = tmp;
				tmp = tmp->next;
			}	
			if (prev == NULL)//while循环中p->data > tmp->data未执行,即需要在tmp前插入
			{
				p->next = *phead;
				*phead = p;
			}
			else
			{
				p->next = prev->next;
				prev->next = p;
			}
			tmp = *phead;
			prev = NULL;
		}
	}

	

	
}
ElemType SListFront(SList phead)//头元素
{
	assert(phead != NULL);
	return phead->data;
}
ElemType SListBack(SList phead)//尾元素
{
	assert(phead != NULL);
	SListNode *p = phead;
	while (p->next != NULL)
		p = p->next;
	return p->data;
}
void SListEraseAll(SList *phead, ElemType key) //按值删除所有值
{
	assert(phead != NULL); 
	int num = 0;
	SList p = SListFind(*phead, key);//定位到key第一次出现的位置
	if (p == NULL)
	{
		printf("该链表不存在该值!删除失败!");
		return;
	}
	for (; p != NULL; p = p->next)
	{
		if (p->data == key)
			num++;
	}
	for (int i = 0; i < num; i++)
	{
		SList p = SListFind(*phead, key);
		SList prev = *phead;
		if (prev == p)   
		{
			*phead = p->next;
			free(p);
		}
		else
		{
			while (prev->next != p)
				prev = prev->next;
			prev->next = p->next;
			free(p);
		}
	}
	printf("删除成功!");
}
void SListClear(SList *phead) //清空链表
{
	assert(phead != NULL);
	SListNode *p = NULL;
	while (*phead != NULL)
	{
		p = *phead;
		*phead = p->next;
		free(p);
	}
}
void SListDestroy(SList *phead) //摧毁链表
{
	SListClear(phead);
}
void SListReverse(SList *phead) //链表转置
{
	assert(phead != NULL);
	SListNode *p = *phead;
	SListNode *q = p->next;

	p->next = NULL;
	while (q != NULL)
	{
		p = q;
		q = q->next;
		p->next = *phead;
		*phead = p;
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

数据结构——不带头结点的单链表的基本操作 的相关文章

  • Go协程池设计思路(Task-Job-Worker)

    1 铺垫 xff1a Go 的接收器Receiver 在go语言中 xff0c 没有类的概念 xff0c 但是可以给类型 xff08 结构体 xff0c 自定义类型 xff09 定义方法 所谓方法就是定义了接受者的函数 接受者定义在func
  • 系统间通信1:阻塞与非阻塞式通信A

    版权声明 xff1a 本文引用https yinwj blog csdn net article details 48274255 从这篇博文开始 xff0c 我们将进入一个新文章系列 这个文章系列专门整理总结了目前系统间通信的主要原理 手
  • 系统间通信1:阻塞与非阻塞式通信B

    版权声明 xff1a 本文引用https yinwj blog csdn net article details 48274255 接上篇 xff1a 系统间通信1 xff1a 阻塞与非阻塞式通信A 4 3 NIO通信框架 目前流行的NIO
  • 系统间通信2:通信管理与远程方法调用RMI

    本文引用 https yinwj blog csdn net article details 49120813 RMI Remote Method Invocation xff0c 远程方法调用 RPC Remote Procedure C
  • 系统间通信3:RPC的基本概念

    本文引用 https yinwj blog csdn net article details 49453303 1 概述 经过了详细的信息格式 网络IO模型的讲解 xff0c 并且通过JAVA RMI的讲解进行了预热 从这篇文章开始我们将进
  • 系统间通信4:基本IO通信模型

    本文引用 https blog csdn net yinwenjie article details 48472237 目前常用的IO通信模型包括四种 xff1a 阻塞式同步IO 非阻塞式同步IO 多路复用IO和真正的异步IO 所有IO模式
  • 深入理解Golang中的Context包

    context Context是Go语言中独特的设计 xff0c 在其他编程语言中我们很少见到类似的概念 context Context深度支持Golang的高并发 1 Goroutine和Channel 在理解context包之前 xff
  • ubuntu —— 命令行访问网页

    span class hljs variable style margin 0px padding 0px span sudo apt get install w3m span class hljs variable style margi
  • VINS-Mono 加rgbd

    通过对比VINS Mono与其RGBD版本 xff0c 分析其改动思路 一 feature tracker feature tracker node cpp 头文件加入了ros的多传感器时间戳 include lt message filt
  • MFC使用HttpGet和HttpPost方法与服务器通信

    处理过程封装到CHttpClient类中 同时支持http和https HttpClient h cpp view plain copy HttpClient h ifndef HTTPCLIENT H define HTTPCLIENT
  • 【Micropython】肝货~使用USB_VCP通过USB串口与树莓派或PC端通信

    为什么要使用USB VCP xff1f Micropython有很多串口 xff0c 例如PYboard xff0c 有5个串口可以使用 xff0c 但是 xff0c 平时我们在做一些项目的时候 xff0c 需要使用的引脚较多 xff0c
  • npm 401 BASIC realm=“Sonatype Nexus Repository Manager“

    今天在做vue项目 切换私服nexus npm login时 遇到了下面的问题error Unable to authenticate need BASIC realm 61 34 Sonatype Nexus Repository Man
  • 通过HTTP协议利用VC++ POST通信开发

    转载地址 xff1a https blog csdn net lhsxsh article details 4200486 void CMFCForm1Dlg OnBnClickedOk TODO 在此添加控件通知处理程序代码 CDialo
  • java源码解析JavaParser

    package com bootdo jparser import java io File import java io FileNotFoundException import com github javaparser JavaPar
  • 关于串口通讯查询与中断两种方式

    串口通讯有查询与中断两种方式 2011 09 13 13 31 我们知道串口通讯有查询与中断两种方式 xff0c 但是对于两种方式的区别很多人并不是非常清楚 xff0c 对于两者的实现到底有和不同呢 xff1f 让我们简单的总结如下 xff
  • linux 下postgresql遇到几个问题

    问题1 xff1a Job for postgresql service failed because the control process exited with error code See 34 systemctl status p
  • ActiveMQ连接数过多,导致ActiveMQ无法正常接入数据

    ActiveMQ跑了一段时间 xff0c 会出现连接数据过多的报错 Could not accept connection org apache activemq transport tcp ExceededMaximumConnectio
  • Axure嵌入Echarts图表--javascript (js)注入

    前言 用Axure做Web原型设计时 xff0c 经常会有图表 特别是大屏可视化或者数据可视化的原型中就更为常见 传统的方法是通过既有的图形或者曲线加上文字来实现 由于Axure可以通过javascript注入 的方法进行简单的拓展 xff
  • Axure嵌入Highcharts图表--javascript (js)注入

    前言 上次发现可以通过javascript js 注入实现在Axure 里引用Echarts图表 xff0c 提升原型展现能力 xff0c 特别是在高保真原型 既然可以实现Echarts的图表引用 xff0c 那么能否用同样的方法引用Hig
  • 一个比较好用的网络爬虫软件GooSeeker

    最近要搜集一些新闻语料 xff0c 看论文发现一个叫GooSeeker的爬虫软件还不错 xff0c 看了一天多的教程终于跑起来了 xff0c 趁着这会在抓新浪新闻过来发篇blog 这个爬虫是作为Firefox的插件出现的 一开始还觉得不够强

随机推荐

  • LibreELEC(kodi)安装

    想体验 xff08 折腾 xff09 kodi xff0c 刚好手上有个空置的树莓派 xff0c 而LibreELEC是轻量化kodi分支的开源系统 xff0c 本文介绍自动和手动安装LibreELEC xff08 LE xff09 原文地
  • LibreELEC(kodi)安装 IPTV

    kodi的PVR IPTV Simple Client插件通过直播源可以实现类似电视机顶盒播放电视节目的基本功能 xff0c 本文将介绍LibreELEC xff08 kodi xff09 安装和简单设置的PVR IPTV Simple C
  • Axure中继器组件化GIS地图

    虽然可以使用JavaScript注入的方式将GIS地图嵌入Axure xff0c 但每次使用地图都需要重复嵌入并修改代码 xff0c 不太方便 那么 xff0c 能不能实现组件化呢 xff1f 我们可以使用中继器 xff08 repeate
  • 比特米盒子刷安卓ATV6.0

    最近海鲜市场有很多比特米盒子 xff0c 50多块包邮 xff0c 买来的盒子回来折腾下 xff0c 买回来发现一直卡在 系统启动 34 中无法进入 xff0c 不知道原来的是啥系统 xff0c 看来只能找找线刷的办法 xff0c 重新拯救
  • Visual Studio Code(VSCode) 编辑/编译/调试 C++ 代码

    前言 最近想要切换编辑工具 xff0c 之前工作中使用过 Source Insight xff0c Eclipse xff0c CLion 来写 C 43 43 代码 目前来说 Source Insight 已经非常古老 xff0c 只有编
  • Visual Studio Code(vscode) 格式化C++代码

    前言 vscode 自带的代码格式化工具不太好用 xff0c 因此我们需要有额外的代码格式化插件进行辅助 xff0c 一般情况下都使用 clang format 格式化 xff0c 这里是对 vscode 安装和使用 clang forma
  • C++如何监听http请求

    下面有个例子 xff0c 基于 Windows 的 xff0c 编译完 xff0c 运行 WebSrv 7070 即可 在程序的目录中放一个 index html 文件 Copyright c 2002 2005 by Zhang Huiy
  • 我的网页作品(div+css)

    前段时间为一个育儿网站做了一个个人空间主页 xff0c 这可是我的处女座 呵呵 请点击查看 xff1a Files shiyangxt baobaoke rar
  • 我用Visual Basic做的多模式计算器(应用小软件)!

    前一段时间参加了一个校内组织的IT实践大赛 xff0c 虽然当时没什么成熟的技术 xff0c 但是还是参加了 Visual Basic刚学也没多长时间 xff0c 于是就做了这个多模式计算器 xff0c 虽然技术含量不算高 xff0c 一些
  • C语言实现阶乘累加(1!+2!+3!+....+n!=?)

    最近要期末考试 xff0c 复习C语言 xff0c 见到一个看似很简单的问题 就是C语言实现阶乘累加 xff08 1 xff01 43 2 xff01 43 3 43 43 n 61 xff09 本来觉得这个肯定小意思 xff0c 但是修改
  • C++项目工程(包含opencv库以及项目的依赖库移植)编译成android可以使用的so库并在Android studio上调用so库进行使用(血泪操作总结)

    目录结构 概述预先准备编译操作so的函数导出并在android进行调用 概述 最近负责一个android项目需要使用到之前公司师兄编写的c 43 43 算法库 xff0c 一开始并不知道c 43 43 项目可以移植给android项目使用
  • C语言:用递归实现将输入的整数按逆序输出。如输入12345,则输出54321。

    这个程序是我对构造函数有个更深的认识 首先构造函数要先从头至尾走一边才会输出 xff0c 无论输出语句加的位置 xff08 循环内 xff0c 条件语句内 除外 xff09 然后构造函数递归可以把问题简单化 xff0c 本题如果按常规思路
  • Visual Basic函数大全!

    VB函数大全 Abs 函数 返回数的绝对值 And 运算符 执行两个表达式的逻辑连接 Array 函数 返回含一数组的 变体 Asc 函数 返回字符串首字母的 ANSI 字符代码 赋值运算符 61 给变量或属性赋值 Atn 函数 返回数的反
  • 数据结构与算法:哈夫曼树(源码)!

    这些天明白了一个道理 xff0c 搞技术也是需要激情的 也不知道为什么这段过的感觉特别的不爽 xff0c 也不知道是因为快要考试了 xff0c 心里没底 xff0c 而带来的恐惧 xff0c 还是 搞技术太久 xff0c 心里想放个假 xf
  • SSH超实用分页实现(原创开源)!

    SSH的分页网上有不少的例子 xff0c 有利用session的 xff0c 有利用分页组件的 我几个师兄原来搞的SSH项目也有一个成熟的分页插件 具体业务实现类中的分页方法 xff1a lt bgsound cep 61 34 0 34
  • 欢迎访问我的主博(http://shiyangxt.cnblogs.com)

    JavaEye的朋友 xff0c 大家好 我是一名大二的学生 xff0c 对编程技术怀有很大的热情 我的技术方向是Java xff0c 但是我的主博并不在这里 xff0c 而在博客园 xff0c 欢迎大家访问我的主博 施杨de编程世界 我渴
  • Linux应用编程---14.UDP服务器、客户端编程

    Linux应用编程 14 UDP服务器 客户端编程 之前有介绍过UDP是一种无连接 尽最大努力交付 面向报文的协议 应用层交给UDP多长的报文 xff0c UDP就照样发送 Linux下UDP属于数据报socket 数据报socket流程图
  • 0816网络编程day5

    include lt stdio h gt include lt sys types h gt include lt sys socket h gt include lt arpa inet h gt include lt netinet
  • STL容器特征

    STL中顺序容器类和关联容器类的主要特征如下 xff1a 1 vector 内部数据结构 xff1a 数组 随机访问每个元素 xff0c 所需要的时间为常量 在末尾增加或删除元素所需时间与元素数目无关 xff0c 在中间或开头增加或删除元素
  • 数据结构——不带头结点的单链表的基本操作

    数据结构 不带头节点的单链表的基本操作 结构体的创建 xff1a span class token keyword typedef span span class token keyword struct span SListNode sp