代码实现链表的操作函数

1.首先是尾插 ,要实现尾插,首先的先有一个链表,并且为空。

即先构造一个链表,并且进行初始化。

//构造链表
typedef int DataType;
typedef struct SListNode {
DataType data;
struct SListNode *pNext;
} SListNode;
// 初始化
void SListInit(SListNode **ppFirst)
{
assert(ppFirst != NULL);
*ppFirst = NULL;
}
进行尾插前,我们的在构造一个新链表,用来存放尾插后形成的新链表。
SListNode * CreateNewNode(int data)
{SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));assert(pNewNode);pNewNode->data = data;pNewNode->pNext = NULL;return pNewNode;
}
下面进行尾插
void PushBack(SListNode **ppFirst, DataType data)
{assert(ppFirst != NULL);SListNode *pNewNode = CreateNewNode(data);if (*ppFirst == NULL) {*ppFirst = pNewNode;return;}SListNode *pNode;pNode = *ppFirst;while (pNode->pNext != NULL) {pNode = pNode->pNext;}// pNode 就是倒数第一个pNode->pNext = pNewNode;
}
再加上打印函数与测试函数,main函数。
//print
void Print(SListNode *pFirst)
{SListNode *pNode;for (pNode = pFirst; pNode; pNode = pNode->pNext) {printf("%d -> ", pNode->data);}printf("NULL\n");
}
//测试函数
void TestSList()
{SListNode *pFirst;SListInit(&pFirst);assert(pFirst == NULL);PushBack(&pFirst, 1);assert(pFirst != NULL);Print(pFirst);PushBack(&pFirst, 2);PushBack(&pFirst, 3);PushBack(&pFirst, 4);Print(pFirst);
}
//main函数
#include"SList.h"
int main(){TestSList();system("pause");
}
效果如下

2.头插

void PushFront(SListNode **ppFirst, DataType data){assert(ppFirst != NULL);SListNode *pNewNode = CreateNewNode(data);pNewNode->pNext = *ppFirst;
*ppFirst = pNewNode;
}
测试函数如下:
PushFront(&pFirst, 5);PushFront(&pFirst, 8);Print(pFirst);

3.按下标插入(令给定下标是pos,pos一定存在)

void Insert(SListNode **ppFirst, SListNode *pPos, DataType data)
{
assert(ppFirst != NULL);
SListNode *pNode;
pNode = *ppFirst;
// pPos 是第一个结点地址
if (pPos == *ppFirst) {
PushFront(ppFirst, data);
return;
}
while (pNode->pNext != pPos){
pNode = pNode->pNext;
}
SListNode *pNewNode = CreateNewNode(data);
pNode->pNext = pNewNode;
pNewNode->pNext = pPos;
}
进行按给定位置插入 需确定pos位置,需定义find函数
//find
SListNode * Find(SListNode *pFirst, DataType data)
{SListNode *pNode;
for (pNode = pFirst; pNode; pNode = pNode->pNext) {if (pNode->data == data) {return pNode;}}
return NULL;
}
测试代码如下:
SListNode *pFound = Find(pFirst, 3);if (pFound == NULL) {printf("没有找到\n");}else {printf("%d\n", pFound->data);Insert(&pFirst, pFound, 100);}
Print(pFirst);
效果如下:

二、删除

1.头删

void PopFront(SListNode **ppFirst)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);SListNode *pOldFirst = *ppFirst;
*ppFirst = (*ppFirst)->pNext;
free(pOldFirst);
}
测试代码如下:
PopFront(&pFirst);Print(pFirst);
效果如下:

2.尾删

void PopBack(SListNode **ppFirst)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);
if ((*ppFirst)->pNext == NULL) {
free(*ppFirst);
*ppFirst = NULL;
return;
}
SListNode *pNode = *ppFirst;
while (pNode->pNext->pNext != NULL)
{
pNode = pNode->pNext;
}
free(pNode->pNext);
pNode->pNext = NULL;
}
测试函数如下:
PopBack(&pFirst);Print(pFirst);
效果如下:

3.按位置删除(根据结点地址删除,结点肯定在链表里,令节点位置为pPos)

void Erase(SListNode **ppFirst, SListNode *pPos)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);
if (*ppFirst == pPos) {
PopFront(ppFirst);
return;
}
SListNode *pCur;
for (pCur = *ppFirst; pCur->pNext != pPos; pCur = pCur->pNext) {
}
// pCur 就是 pPos的前一个
pCur->pNext = pPos->pNext;
free(pPos);
}
测试函数如下:
SListNode *pFound = Find(pFirst, 1);{  if (pFound == NULL) {printf("没有找到\n");}else {printf("%d\n", pFound->data);Erase(&pFirst, pFound);}SListDestroy(&pFirst);}
运行效果如下

4.按值删除(根据数据去删除,删除遇到的第一个结点)

void Remove(SListNode **ppFirst, DataType data)
{
SListNode *pFound = Find(*ppFirst, data);
if (pFound != NULL) {
Erase(ppFirst, pFound);
}
}
测试函数如下:
void TestRemove()
{SListNode *pFirst;SListInit(&pFirst);
PushBack(&pFirst, 4);
PushBack(&pFirst, 3);
PushBack(&pFirst, 1);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 5);
PushBack(&pFirst, 3);
Print(pFirst);
Remove(&pFirst, 3);
Print(pFirst);
运行效果如图

5.按值删除( 根据数据去删除,删除遇到的所有结点)

void RemoveAll(SListNode **ppFirst, DataType data)
{
SListNode *pNode = *ppFirst;
SListNode *pNext;
while (pNode->pNext) {
if (pNode->pNext->data == data) {
pNext = pNode->pNext;
pNode->pNext = pNode->pNext->pNext;
free(pNext);
}
else {
pNode = pNode->pNext;
}
}
if ((*ppFirst)->data == data) {
PopFront(ppFirst);
}
}
测试函数如下:
RemoveAll(&pFirst, 3);
Print(pFirst);
测试效果如下

源代码如下:

Hello.h
#pragma once
#include <stdlib.h>
#include <assert.h>
#include <stdio.h>
typedef int DataType;
typedef struct SListNode {DataType  data;struct SListNode *pNext;
}   SListNode;
// 初始化
void SListInit(SListNode **ppFirst)
{assert(ppFirst != NULL);*ppFirst = NULL;
}
SListNode * CreateNewNode(int data)
{SListNode *pNewNode = (SListNode *)malloc(sizeof(SListNode));assert(pNewNode);pNewNode->data = data;pNewNode->pNext = NULL;return pNewNode;
}
//打印函数
void Print(SListNode *pFirst)
{SListNode *pNode;for (pNode = pFirst; pNode; pNode = pNode->pNext) {printf("%d -> ", pNode->data);}printf("NULL\n");
}
// 销毁
void SListDestroy(SListNode **ppFirst)
{assert(ppFirst != NULL);SListNode *pNode, *pNext;pNode = *ppFirst;while (pNode != NULL) {pNext = pNode->pNext;free(pNode);pNode = pNext;}*ppFirst = NULL;
}// 查找,返回遇到的第一个
// 如果找到了,返回结点地址
// 否则返回 NULL
SListNode * Find(SListNode *pFirst, DataType data)
{SListNode *pNode;for (pNode = pFirst; pNode; pNode = pNode->pNext) {if (pNode->data == data) {return pNode;}}return NULL;
}
// 增删改查// 尾插
void PushBack(SListNode **ppFirst, DataType data)
{assert(ppFirst != NULL);
SListNode *pNewNode = CreateNewNode(data);if (*ppFirst == NULL) {*ppFirst = pNewNode;return;}SListNode *pNode;pNode = *ppFirst;while (pNode->pNext != NULL) {pNode = pNode->pNext;}// pNode 就是倒数第一个pNode->pNext = pNewNode;
}
/*
// 头插
void PushFront(SListNode **ppFirst, DataType data)
{
assert(ppFirst != NULL);
SListNode *pNewNode = CreateNewNode(data);
pNewNode->pNext = *ppFirst;
*ppFirst = pNewNode;
}
// 插入到给定结点 pPos 前,pPos 肯定在链表里
void Insert(SListNode **ppFirst, SListNode *pPos, DataType data)
{
assert(ppFirst != NULL);
SListNode *pNode;
pNode = *ppFirst;
// pPos 是第一个结点地址
if (pPos == *ppFirst) {
PushFront(ppFirst, data);
return;
}
while (pNode->pNext != pPos){
pNode = pNode->pNext;
}
SListNode *pNewNode = CreateNewNode(data);
pNode->pNext = pNewNode;
pNewNode->pNext = pPos;
}
*/
// 头删
void PopFront(SListNode **ppFirst)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);
SListNode *pOldFirst = *ppFirst;
*ppFirst = (*ppFirst)->pNext;
free(pOldFirst);
}
// 尾删
void PopBack(SListNode **ppFirst)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);
if ((*ppFirst)->pNext == NULL) {
free(*ppFirst);
*ppFirst = NULL;
return;
}
SListNode *pNode = *ppFirst;
while (pNode->pNext->pNext != NULL)
{
pNode = pNode->pNext;
}
free(pNode->pNext);
pNode->pNext = NULL;
}
// 根据结点地址删除,结点肯定在链表里
void Erase(SListNode **ppFirst, SListNode *pPos)
{
assert(ppFirst != NULL);
assert(*ppFirst != NULL);
if (*ppFirst == pPos) {
PopFront(ppFirst);
return;
}
SListNode *pCur;
for (pCur = *ppFirst; pCur->pNext != pPos; pCur = pCur->pNext) {
}
// pCur 就是 pPos的前一个
pCur->pNext = pPos->pNext;
free(pPos);
}
/*
void TestSList()
{SListNode *pFirst;SListInit(&pFirst);assert(pFirst == NULL);PushBack(&pFirst, 1);assert(pFirst != NULL);Print(pFirst);PushBack(&pFirst, 1);PushBack(&pFirst, 2);PushBack(&pFirst, 3);Print(pFirst);PushFront(&pFirst, 5);PushFront(&pFirst, 8);Print(pFirst);SListNode *pFound = Find(pFirst, 3);if (pFound == NULL) {printf("没有找到\n");}else {printf("%d\n", pFound->data);Insert(&pFirst, pFound, 100);}Print(pFirst);PopFront(&pFirst);Print(pFirst);PopBack(&pFirst);Print(pFirst);SListNode *pFound = Find(pFirst, 9);{  if (pFound == NULL) {printf("没有找到\n");}else {printf("%d\n", pFound->data);Erase(&pFirst, pFound);}SListDestroy(&pFirst);}
}
*/
// 根据数据去删除,删除遇到的第一个结点
void Remove(SListNode **ppFirst, DataType data)
{
SListNode *pFound = Find(*ppFirst, data);
if (pFound != NULL) {
Erase(ppFirst, pFound);
}
}
// 根据数据去删除,删除遇到的所有结点
void RemoveAll(SListNode **ppFirst, DataType data)
{
SListNode *pNode = *ppFirst;
SListNode *pNext;
while (pNode->pNext) {
if (pNode->pNext->data == data) {
pNext = pNode->pNext;
pNode->pNext = pNode->pNext->pNext;
free(pNext);
}
else {
pNode = pNode->pNext;
}
}
if ((*ppFirst)->data == data) {
PopFront(ppFirst);
}
}
void TestRemove()
{SListNode *pFirst;
SListInit(&pFirst);
PushBack(&pFirst, 4);
PushBack(&pFirst, 3);
PushBack(&pFirst, 1);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 3);
PushBack(&pFirst, 5);
PushBack(&pFirst, 3);
Print(pFirst);
Remove(&pFirst, 3);
Print(pFirst);
RemoveAll(&pFirst, 3);
Print(pFirst);
}
main.c
#include"Hello.h"
int main(){TestRemove();//TestSList();system("pause");
}

到此,单链表的基本功能差不多都实现了。

数据结构之实现链表的基本操作 增减删改相关推荐

  1. c语言实现双链表的基本操作—增删改查

    //初始化 Node*InitList() {Node*head=(Node*)malloc(sizeof(Node));if(NULL==head){printf("内存分配失败!&quo ...

  2. 数据结构:单链表的基本操作

    一,链式存储结构 结点在存储器中的位置是任意的,即逻辑上相邻的数据元素在物理上不一定相邻 用一组物理位置任意的存储单元来存放线性表的数据元素,存储单元既可以是连续的,也可以是不连续的,甚至是零散分布在 ...

  3. 数据结构之【线性表】(顺序表、链表的基本操作实现)

    概念 线性表:是N个数据元素的有限序列. 顺序表:用一组地址连续的存储单元依次存储[线性表 ]的数据元素.(区别于有序表:表中的数据元素存在非递增或非递减有序) 链表:用一组任意的存储单元来存储[线性 ...

  4. 数据结构实验3、单链表的基本操作实现

    实验三: 作者说: 写的如果有不太好的地方,欢迎大佬指点! 一.运行效果截图 二.实验要求 实验3.单链表的基本操作实现 (1)实验目的 通过该实验,深入理解链表的逻辑结构.物理结构等概念,掌握链表基 ...

  5. 【数据结构】链表的基本操作

    文章目录 1.单链表的定义 2.单链表上的基本操作 2.1采用头插法建立单链表 2.2采用尾插法建立单链表 2.3按序号查找结点数据 2.4按值查找表结点 2.5插入节点操作 2.6删除节点操作 3. ...

  6. node 获取表单数据 为空_Java实现数据结构之【链表】

    链表相比于前几个章节讲的数据结构而言,是一个真正的动态数据结构也是一个最简单的动态数据结构,我们在后面还会接触更多的动态数据结构,所以对链表有一个理解非常好的基础,就能够更加容易的学习后面更加复杂的数 ...

  7. mysql 修改库的校对集_mysql数据库的基本操作(增删改查、字符集、校对集)

    MySQL数据库概述 MySQL数据库是经典的关系型数据库管理系统,MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Dat ...

  8. 链表c++语言 解析,C++ 单链表的基本操作(详解)

    链表一直是面试的高频题,今天先总结一下单链表的使用,下节再总结双向链表的.本文主要有单链表的创建.插入.删除节点等. 1.概念 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数 ...

  9. 【BUCTOJ】链表的基本操作

    原始题目 题题目描述 链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表.它较顺序表而言在插入和删除时不必移动其后的元素.现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在 ...

最新文章

  1. Linux C++写日志
  2. kali里PHP文件502错误,解决Linux Kali iptables开放22端口失败等一系列问题
  3. srsLTE源码学习:RLC,无线链路控制子层抓包rlc_pcap.h,rlc_pcap.cc
  4. 查看tar文件的顶层目录
  5. mac 截图快捷键
  6. Dom4j中getStringValue()和getText()用法的区别
  7. Java 实现了第三方QQ账号登录(附源码)
  8. linux中tar命令怎么用,linux tar命令使用详解
  9. expdp —— XDB SGA initialization
  10. 苹果怎么信任企业级开发者_苹果企业签名是什么意思?
  11. 安卓手机内外SD卡互换
  12. 软件测试平台的作用以及会包含哪些功能?
  13. Linux的命令和快捷键
  14. python字符串查找位置_python中怎么返回指定查找字符的位置
  15. Linux更改本机ip
  16. 极限学习机(Extreme Learning Machine)(小白之路)
  17. Windows Server 2008 R2 安装SP1补丁出错(0x800f0818)
  18. 剖析云计算技术及架构(1)
  19. python web为什么不火-python为何不火
  20. Python 实现给女朋友的每日微信消息提醒!做一个贴心的程序员!!!

热门文章

  1. 离散数学计算机专业论文,离散数学
  2. sqlserver查看执行计划
  3. 什么是盒子模型中的水平方向的布局
  4. 尘梦回还服务器在维护中是什么意思,20191211维护公告解读
  5. 怎样获取iPhone/ipad的设备ID(UUID)号?
  6. Netbackup 证书过期问题处理办法-NBU Error 8506
  7. .net core + vue项目在windows server2008系统的部署步骤和文件下载
  8. 简单的密码输入验证代码(java)
  9. 动态路由下刷新 页面空白
  10. Elasticsearch-02-es的restapi使用