c++用户管理信息(双向链表)

这篇具有很好参考价值的文章主要介绍了c++用户管理信息(双向链表)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

ListStu双向链表–(把前面的单链表改一下,就直接可以用)

ListStu.h

#pragma once
#include "ClassStu.h"

class ListStu
{
public:
	struct StuNode
	{
		ClassStu m_cStu;//数据
		StuNode* m_pPro;//指向前一个节点
		StuNode* m_pNext;//指向下一个节点


		StuNode()
		{
			m_cStu = 0;
			m_pNext = nullptr;
			m_pPro = nullptr;
		}


		StuNode(ClassStu& Stu)
		{
			m_cStu = Stu;
			m_pNext = nullptr;
			m_pPro = nullptr;

		}
	};

	using pStuNode = StuNode*;
public:
     //迭代器类
	class Iterator
	{
	public:

		Iterator(pStuNode Current,pStuNode Head, pStuNode Vail)
		{
			m_Current = Current;
			m_Head = Head;
			m_Vail = Vail;
		}

		ClassStu& operator*()
		{
			return m_Current->m_cStu;
		}

		Iterator& operator++()
		{
			if (m_Current == nullptr)//不能是空
			{
				return *this;
			}
			if (m_Current == m_Vail)//不能是尾部节点
			{
				return *this;
			}
			m_Current = m_Current->m_pNext;
			return *this;
		}

		Iterator& operator--()
		{
			if (m_Current == nullptr)
			{
				return *this;
			}
			if (m_Current == m_Vail)
			{
				return *this;
			}
			m_Current = m_Current->m_pPro;
			return *this;
		}



		bool operator!=(Iterator Itr)
		{
			return m_Current != Itr.m_Vail;//不等于的时候返回真
		}

	private:
		friend class ListStu;
		pStuNode m_Current;//当前节点
		pStuNode m_Head;//头节点
		pStuNode m_Vail;//尾节点
	};


public:

	/*******************默认构造系列开始*************************/
/*
   * ListStu
   * 参数一 : 无
   * 功能   :默认构造,初始化类成员 --为空
   * 返回值 :无
*/
	ListStu();


/*
	* ListStu
	* 参数一 : int
	* 功能   :默认构造,初始化nCount个成员链表
	* 返回值 :无
*/
	ListStu(int nCount);
/*
	* ~ListStu
	* 参数一 : 无
	* 功能   :默认析构,释放资源
	* 返回值 :无
*/
	~ListStu();

	/*******************默认构造系列结束*************************/

//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//
//----------------------------------------------------------------------------//

	/*******************增删改查系列开始*************************/
/*
	* HeadInsert
	* 参数一 : ClassStu
	* 功能   :从头部插入一个数据
	* 返回值 :ListStu&
*/

	ListStu& HeadInsert(ClassStu& cStu);

/*
	* VailInsert
	* 参数一 : ClassStu
	* 功能   :从尾部插入一个数据
	* 返回值 :ListStu&
*/

	ListStu& VailInsert(ClassStu& cStu);
/*
	* Insert
	* 参数一 : pStuNode 需要插入节点的位置   插在这个节点的pStuNode后面
	* 参数二 : ClassStu& 插入的数据
	* 功能   : 指定位置插入一个数据
	* 返回值 : ListStu&
*/

	ListStu& Insert(Iterator Itr,ClassStu& cStu);


/*
	* Detele
	* 参数一 : pStuNode    删除的前一个节点
	* 功能   : 从链表中删除一个节点
	* 返回值 :ListStu&
*/
	ListStu& Delete(pStuNode PosNode);

/*
	* DeteleHead
	* 参数一 : pStuNode   删除头部节点
	* 功能   : 删除头部节点
	* 返回值 : ListStu&
*/
	ListStu& DeleteHead();


/*
	* DeleteVail
	* 参数一 : pStuNode   删除尾部节点
	* 功能   : 删除尾部节点
	* 返回值 : ListStu&
*/
	ListStu& DeleteVail();
/*
	* DeteleId
	* 参数一 : 索引
	* 功能   : 指定索引从链表中删除一个节点
	* 返回值 : 无
*/
	ListStu& DeteleId(int nIndex);



/*
	* Find
	* 参数一 : int --序号索引
	* 功能   : 通过索引查找到数据
	* 返回值 : 无
*/
	StuNode* Find(int nIndex);


/*
	* FindItr
	* 参数一 : int --序号索引
	* 功能   : 查找到数据
	* 返回值 : Iterator   
*/
	Iterator FindItr(int nIndex);

/*
	* FindFOffset
	* 参数一 : int --序号索引
	* 功能   : 根据索引查找到文件偏移
	* 返回值 : 无
*/
	int FindFOffset(int nIndex);

/*
	* FindId
	* 参数一 :  int --序号索引
	* 功能   : 根据索引查找到用户m_Id
	* 返回值 : 无
*/
	int FindId(int nIndex);

/*
	* UserIdToIndex
	* 参数一 :  int --用户的m_Id
	* 功能   : 用户m_Id --查到链表用户的索引
	* 返回值 : int  nIndex
*/
	int UserIdToIndex(int UserId);

/*
	* UpDate
	* 参数一 : int --序号索引
	* 功能   : 修改用户的数据
	* 返回值 : 无
*/
	void UpDate(int nIndex,ClassStu& cStu);
	/*******************增删改查系列结束*************************/


	/*******************迭代器开始*************************/
/*
	* begin
	* 参数一 : 无
	* 功能   : 迭代器开始
	* 返回值 : Iterator
*/

	Iterator begin()
	{
		return Iterator(m_HeaderStu->m_pNext, m_HeaderStu, m_VailStu);
	}
/*
	* end
	* 参数一 : 无
	* 功能   : 迭代器结束
	* 返回值 : Iterator
*/
	Iterator end()
	{
		return Iterator(m_VailStu, m_HeaderStu, m_VailStu);
	}
	/*******************迭代器结束*************************/

	/*******************内部使用函数系列开始*************************/
/*
	* InitDate
	* 参数一 : int --序号索引
	* 功能   : 初始化类成员
	* 返回值 : 无
*/
	void InitList();



/*
* GetMaxUserId
* 参数一 : 无
* 功能   : 查找用户最大的m_Id
* 返回值 : int
*/
	int GetMaxUserId();


/*
	* size
	* 参数一 : 无
	* 功能   : 获取元素个数
	* 返回值 : int
*/
	int Size();

/*
	* BubbleSort
	* 参数一 : 无
	* 功能   : 根据成员m_Id --冒泡排序
	* 返回值 : 无
*/
	//void BubbleSort();

/*
	* insertionSort
	* 参数一 : 无
	* 功能   : 根据成员m_Id --插入排序法
	* 返回值 : 无
*/
	//void insertionSort();
/*
	* Sort()
	* 参数一 : 无
	* 功能   : 根据成员m_Id --选择性排序法
	* 返回值 : 无
*/
	void Sort();

	/*******************内部使用函数系列结束*************************/

private:
	pStuNode m_HeaderStu;//头节点
	pStuNode m_VailStu;//尾节点
	int m_nCount;//记录有多少个成员
};


ListStu.cpp

#include "ListStu.h"

ListStu::ListStu()
{
	InitList();
}

ListStu::ListStu(int nCount)
{
	InitList();
	for (int i = 0; i < nCount; i++)
	{
		ClassStu cStu;
		VailInsert(cStu);
	}
	
}

ListStu::~ListStu()
{
	//判断是否有成员
	if (m_nCount == 0)
	{
		return;
	}

	//释放资源
	//先赋值下一个,在删除当前,以此类推.
	pStuNode TmpbNode = m_HeaderStu->m_pNext;
	pStuNode TmpfNode = nullptr;
	for (int i = 0; i < m_nCount; i++)
	{
		TmpfNode = TmpbNode->m_pNext;
		delete TmpbNode;
		TmpbNode = TmpfNode;
	}
}

ListStu& ListStu::HeadInsert(ClassStu& cStu)
{
	return Insert(begin(), cStu);
}

ListStu& ListStu::VailInsert(ClassStu& cStu)
{
	return Insert(end(), cStu);
}

ListStu& ListStu::Insert(Iterator Itr, ClassStu& cStu)
{
	if (Itr.m_Current == nullptr)
	{
		return *this;
	}
	auto PosNode = Itr.m_Current;

	pStuNode ListNode = new StuNode(cStu);
	PosNode->m_pPro->m_pNext = ListNode;
	ListNode->m_pPro = PosNode->m_pPro;
	PosNode->m_pPro = ListNode;
	ListNode->m_pNext = PosNode;
	m_nCount++;
	return *this;
}

ListStu& ListStu::Delete(pStuNode PosNode)
{
	//判断传入的指针是否为空
	if (PosNode == nullptr)
	{
		return *this;
	}
	//断链  -- 画图
	PosNode->m_pPro->m_pNext = PosNode->m_pNext;
	PosNode->m_pNext->m_pPro = PosNode->m_pPro;
	//释放资源
	delete PosNode;
	//元素个数减减
	m_nCount--;
	return *this;
}

ListStu& ListStu::DeleteHead()
{

	return Delete(m_HeaderStu->m_pNext);
}

ListStu& ListStu::DeleteVail()
{
	if (m_VailStu->m_pPro == m_HeaderStu)
	{
		return *this;
	}
	return Delete(m_VailStu->m_pPro);
}

ListStu& ListStu::DeteleId(int nIndex)
{
	if (nIndex == 0)//索引为0 就是删除头部
	{
		return DeleteHead();
	}
	if (nIndex == (m_nCount-1))//索引等于元素个数就是删除尾部
	{
		return DeleteVail();
	}
	//查找需要删除的节点  
	pStuNode DeleteNode = Find(nIndex);
	//进行删除 并返回
	return Delete(DeleteNode);
}





ListStu::StuNode* ListStu::Find(int nIndex)
{

	//判断 成员个数不为0  nIndex是否有效的值
	if (m_nCount < 1 ||nIndex < 0 || nIndex > m_nCount)
	{
		return nullptr;
	}

	//遍历查找数据    
	pStuNode FindNode = m_HeaderStu->m_pNext;

	for (int i = 0; i < nIndex; i++)
	{
		FindNode = FindNode->m_pNext;

	}
	return FindNode;
}

ListStu::Iterator ListStu::FindItr(int nIndex)
{
	return Iterator(Find(nIndex),m_HeaderStu,m_VailStu);
}

int ListStu::FindFOffset(int nIndex)
{
	pStuNode pFindNode = Find(nIndex);
	if (pFindNode == nullptr)
	{
		return 0;
	}
	return pFindNode->m_cStu.m_FileOffset;
}

int ListStu::FindId(int nIndex)
{
	pStuNode pFindNode = Find(nIndex);
	if (pFindNode == nullptr)
	{
		return 0;
	}
	return pFindNode->m_cStu.m_Id;
}

int ListStu::UserIdToIndex(int UserId)
{
	int nIndex = 0;
	for (auto Val : *this)
	{
		if (UserId == Val.m_Id)
		{
			return nIndex;
		}
		nIndex++;
	}
	return -1;
}

void ListStu::UpDate(int nIndex, ClassStu& cStu)
{

	//先找到要修改的数据
	pStuNode pUpDate = Find(nIndex);
	//替换数据   -- cStu里面会自动释放资源
	pUpDate->m_cStu = cStu;
}

void ListStu::InitList()
{
	m_HeaderStu = new StuNode;
	m_VailStu = new StuNode;

	m_HeaderStu->m_pNext = m_VailStu;
	m_VailStu->m_pPro = m_HeaderStu;
	m_nCount = 0;
}

int ListStu::GetMaxUserId()  //已经排好序的,只要取尾节点的前一个节点的m_Id
{
	return m_VailStu->m_pPro->m_cStu.m_Id;
}

int ListStu::Size()
{
	return m_nCount;
}




	void ListStu::Sort()//适合用选择性排序法了
	{
		auto nTmp = m_HeaderStu->m_pNext;//第一个节点数据
		auto cTmp = nTmp->m_pNext;//第二个节点数据
		for (int i = 0; i < m_nCount - 1; i++)
		{
			for (int j = 0 + i; j < m_nCount - 1; j++)
			{

				if ((nTmp->m_cStu.m_Id) > (cTmp->m_cStu.m_Id))//不停的遍历cTmp下一个
				{
					//交换数据就好
					auto nNumber = nTmp->m_cStu;
					nTmp->m_cStu = cTmp->m_cStu;
					cTmp->m_cStu = nNumber;
				}
				cTmp = cTmp->m_pNext;

			}
			nTmp = nTmp->m_pNext;
			cTmp = nTmp->m_pNext;//重新赋值cTmp为nTmp的下一个节点
		}

	}




文章来源地址https://www.toymoban.com/news/detail-836420.html

到了这里,关于c++用户管理信息(双向链表)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 编程题实训-基于链表的图书信息管理

    第1关:基于链式存储结构的图书信息表的创建和输出  任务描述 本关任务:定义一个包含图书信息(书号、书名、价格)的链表,读入相应的图书数据来完成图书信息表的创建,然后统计图书表中的图书个数,同时逐行输出每本图书的信息。 编程要求 输入 输入n+1行,其中

    2024年02月06日
    浏览(35)
  • JavaEE 项目:用户信息管理系统

    目录 项目介绍 数据库设计 各包结构设计与说明 功能实现 1. 登录功能 2. 分页查询、模糊查询 3. 增、删、改操作 总结 本项目主要实现了对 用户信息的管理 ,能够在客户端很好的操作各个功能,并实时更新用户数据。采用  MySQL数据库  存储数据, JDBC  连接数据库, Servl

    2024年02月08日
    浏览(62)
  • linux之Ubuntu系列(五)用户管理、查看用户信息 终端命令

    创建用户 、删除用户、修改其他用户密码 的终端命令都需要通过 sudo 执行 创建用户 设置密码 删除用户 sudo useradd -m -g 组名 新建用户名 添加新用户 -m:自动建立用户 家目录 -g:指定用户所在的组。否则会建立一个和用户同名的组 设置新增用户的密码,没有密码,是无法s

    2024年02月16日
    浏览(43)
  • Django 框架添加管理员,完成对普通用户信息管理

    前情回顾:Django框架 完成用户登录注册 一般管理员都是直接指定,不开放页面注册,可以直接手动在数据库添加,Django框架提供了方法,让我们直接创建管理员,步骤如下: 打开pycharm下面的命令行终端 输入命令 按照提示进行输入信息 打开数据库,可以看出,已经帮我们插

    2024年01月16日
    浏览(45)
  • 什么是双向链表,一篇搞懂双向链表

    还不清楚单向链表的同学可以去看我另一篇文章,实践总结:一篇搞懂链表——单链表和双指针技巧 首先,我们先看下双向链表(下文用双链表表述)的图示,见下图: 与单链表不同的是,双链表有两个方向,对应单链表节点中的一个引用字段next,双链表每个节点中都含有

    2024年03月13日
    浏览(46)
  • 【LeetCode双向链表】LRU详解,双向链表实战

    请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果 key 存在于缓存中,则返回的值,否则返回 -1 。 void put(int key, int value) 如果 key 已经存在,

    2024年02月06日
    浏览(48)
  • JAVAWEB学生信息管理系统保姆级教程(增删改查+<普通用户和管理员>登录注册+Filter+mysql+批量删除信息+用户退出登录注销)eclipse版(升级版)

    该项目源码地址: 源码地址请点击这里哟!         AdminBean.java        对数据库里的用户名的表的数据进行封装。         StudentBean.java         对数据库里的学生信息的表的数据进行封装。         AdminDao.java         实现登录和注册的方法。         

    2024年02月08日
    浏览(65)
  • [JS与链表]双向链表

    阅读本文前请先阅读 [JS与链表]普通链表_AI3D_WebEngineer的博客-CSDN博客 类的继承可以使用extends,让子类继承父类的属性和方法。 而在子类内部(构造函数constructor)必须调用super()实现继承( super()代表父类构造函数 ) 双向链表与普通链表的区别在于:普通链表的节点是链向下

    2024年02月05日
    浏览(53)
  • 链表拓展之双向链表

    在前面已经总结了单链表,有了单链表的基础会很好理解双链表的实现,忘记了可以跳转——http://t.csdnimg.cn/GFPk9 接下来就由我带着各位看官来认识今天的主角吧~ 在单链表的基础上,它有两个方向的链接,一个链接指向前一个节点,另一个链接指向下一个节点。 每个节点通

    2024年04月26日
    浏览(30)
  • 双向链表超详解——连我奶奶都能学会的复杂链表(带头双向循环)

    前面学过单向链表,单向链表其实就是单向不带头的非循环链表,它不能随机查找,必须从第一个结点开始一个一个的遍历,查找效率比较低,且只有一个指向下一个结点的指针next,它想找到上一个结点还是比较困难的,所以我们今天学习的 双向链表 就很好的弥补了它的一

    2024年02月05日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包