数据结构【单链表基本操作】
时间:2022-07-22
本文章向大家介绍数据结构【单链表基本操作】,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
包含单链表的创建、遍历、反转(指针替换、递归)、排序、插入、删除
// list_2.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
using namespace std;
typedef struct Node
{
int nData; //数据域
Node* pNext; //指针域 指向下一个与自身类型相同的节点
}*PNODE;
PNODE create_list(); //创建链表
void traverse_list(const PNODE pHead); //遍历链表
void inversion_list(PNODE pHead); //反转链表
bool isEmpty_list(const PNODE pHead); //判断链表是否为空
PNODE inversion_list2(PNODE pHead);
void insert_list(PNODE pHead, int nPos, int nValue);
int getListLen(const PNODE pHead);
void delete_list(PNODE pHead, int nPos, int * nValue);
void sort_list(PNODE pHead);
//链表插入元素
void insert_list(PNODE pHead, int nPos, int nValue)
{
int nListLen = getListLen(pHead);
if (nPos < 1 || nPos > nListLen + 1)
{
return;
}
int i = 1;
PNODE pNode = pHead->pNext;
while (nullptr != pNode && i < nPos - 1)
{
pNode = pNode->pNext;
++i;
}
PNODE pInsertNode = (PNODE)malloc(sizeof(Node));
pInsertNode->nData = nValue;
PNODE pTempNode = pNode->pNext;
pNode->pNext = pInsertNode;
pInsertNode->pNext = pTempNode;
}
//获取链表个数
int getListLen(const PNODE pHead)
{
int nLen = 0;
PNODE pNode = pHead->pNext;//计算长度不算头节点
while (nullptr != pNode)
{
pNode = pNode->pNext;
++nLen;
}
return nLen;
}
//删除链表元素
void delete_list(PNODE pHead, int nPos, int * nValue)
{
if (isEmpty_list(pHead) || nPos < 1 || nPos > getListLen(pHead))
{
return;
}
int i = 1;
PNODE pNode = pHead->pNext;
while (nullptr != pNode && i < nPos - 1)
{
pNode = pNode->pNext;
++i;
}
PNODE pDeleteNode = pNode->pNext;
*nValue = pDeleteNode->nData;
PNODE pTempNode = pDeleteNode->pNext;
//让链表连起来
pNode->pNext = pTempNode;
free(pDeleteNode);
}
//冒泡,只替换数据
void sort_list(PNODE pHead)
{
//链表为空或者只有一个有效节点不排序
if (isEmpty_list(pHead) || nullptr == pHead->pNext->pNext)
{
return;
}
PNODE pNode = pHead->pNext;
for (; nullptr != pNode; pNode = pNode->pNext)
{
PNODE pNode2 = pNode->pNext;
for (;nullptr != pNode2 && pNode != pNode2; pNode2 = pNode2->pNext)
{
if (pNode->nData > pNode2->nData)
{
int nValue = pNode->nData;
pNode->nData = pNode2->nData;
pNode2->nData = nValue;
}
}
}
}
//递归反转链表
PNODE inversion_list2(PNODE pHead)
{
if (nullptr == pHead || nullptr == pHead->pNext)
{
return pHead;
}
else
{
PNODE pTemp = inversion_list2(pHead->pNext);
pHead->pNext->pNext = pHead; // 让最后一个节点指回去,这里形成了链表循环
pHead->pNext = nullptr; //这里断开后,节点刚好反转
return pTemp;
}
}
int main()
{
PNODE pHead = create_list();
if (nullptr == pHead)
{
exit(-1);
}
sort_list(pHead);
traverse_list(pHead);
inversion_list(pHead);
traverse_list(pHead);
PNODE pTempNode = inversion_list2(pHead->pNext);
pHead->pNext = pTempNode;
traverse_list(pHead);
insert_list(pHead, 6, 66);
traverse_list(pHead);
int nDeleteValue = 0;
delete_list(pHead, 4, &nDeleteValue);
cout << "删除的元素为:" << nDeleteValue << endl;
traverse_list(pHead);
}
//创建非循环单向链表
PNODE create_list()
{
int nNodeLen = 0;
cout << "请输入创建链表的个数:";
cin >> nNodeLen;
if (0 == nNodeLen)
{
return nullptr;
}
//先创建头节点
PNODE pHead = (PNODE)malloc(sizeof(Node));
if (nullptr == pHead)
{
return nullptr;
}
//让头结点的指针域初始化为空
pHead->pNext = nullptr;
//定义临时节点,永远指向最后一个节点
PNODE pTempNode = pHead;
for (int i = 1; i <= nNodeLen; i++)
{
int nValue = 0;
printf_s("请输入第%d个节点的值:", i);
cin >> nValue;
//创建新节点
PNODE pNewNode = (PNODE)malloc(sizeof(Node));
//判断内存是否申请成功
if (nullptr == pNewNode)
{
return nullptr;
}
//给节点赋值
pNewNode->nData = nValue;
pNewNode->pNext = nullptr;
//把新节点挂在尾结点上
pTempNode->pNext = pNewNode;
//让临时节点指向新的尾结点
pTempNode = pNewNode;
}
return pHead;
}
//遍历链表
void traverse_list(const PNODE pHead)
{
//先从头节点的指针域获取到首节点
PNODE pTraverseNode = pHead->pNext;
while (nullptr != pTraverseNode)
{
cout << pTraverseNode->nData;
cout << "t";
//把当前节点的下一个节点地址赋值给pTraverseNode
pTraverseNode = pTraverseNode->pNext;
}
cout << endl;
return;
}
void inversion_list(PNODE pHead)
{
if (isEmpty_list(pHead) || nullptr == pHead->pNext->pNext)
{
return;
}
PNODE pPrevtNode = pHead->pNext;
PNODE pCurrentNode = pPrevtNode->pNext;
pPrevtNode->pNext = nullptr;
while (nullptr != pCurrentNode)
{
PNODE pTempNode = pCurrentNode->pNext;
pCurrentNode->pNext = pPrevtNode;
pPrevtNode = pCurrentNode;
pCurrentNode = pTempNode;
}
pHead->pNext = pPrevtNode;
return;
}
bool isEmpty_list(const PNODE pHead)
{
//如果头节点的指针域指向的内容为空,那么就是空链表
if (nullptr == pHead->pNext)
{
return true;
}
return false;
}
- 【Android基础】Activity的生命周期函数
- 七种常用回归技术,如何正确选择回归模型?
- 爬取拉勾网大数据相关岗位薪资信息存到excel,并作数据分析
- 【Windows编程】系列第五篇:GDI图形绘制
- 抓取链家官网北京房产信息并用python进行数据挖掘
- 用R语言做钻石价格预测
- 2分钟完成30*15页拉勾网职位需求关键词的抓取
- 【专业技术】Linux设备驱动第七篇:高级字符驱动操作之阻塞IO
- Python抓取上海各地区房价平均值
- R语言分析 老九门 到底谁是主角
- 【编程基础】C语言位
- 【专业技术】Android数据保存之文件保存
- 手工创建/删除数据库的步骤
- 用shell帮助解决ORA问题
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 嵌套滑动通用解决方案--NestedScrollingParent2
- Python 爬取留言板留言(一):单进程版+selenium模拟
- Glide-图片加载框架全解(一)- 基本用法
- Python全栈(六)项目前导之1.Redis介绍及数据类型介绍
- 网络请求框架OkHttp3全解系列(一):OkHttp的基本使用
- 网络请求框架OkHttp3全解系列 - (二)OkHttp的工作流程分析
- 这次,我把Android事件分发机制翻了个遍
- 网络请求框架OkHttp3全解系列 - (三)拦截器详解1:重试重定向、桥、缓存(重点)
- Python全栈(七)Flask框架之4.Flask模板继承与案例练习
- 你想要的系列:网络请求框架OkHttp3全解系列 - (四)拦截器详解2:连接、请求服务(重点)
- 不会玩阴阳师的我带你一键下载《阴阳师:百闻牌》所有卡牌并调用百度OCR识别文字信息
- 微信小程序生命周期学习笔记-页面篇
- Python 字典 使用技巧
- 微信小程序生命周期学习笔记-组件
- C语言入门系列之2.数据类型、运算符和表达式