【Data_Structure笔记2】线性表的链式存储【单链表】
来源:互联网 发布:js秒杀脚本 编辑:程序博客网 时间:2024/06/06 02:40
/************************************************************************************************************************文件说明: 线性表的链式存储之【单链表】、【双链表】、【循环链表】、【静态链表】详细说明: 【1】由于顺序表的插入、删除操作需要大量的移动元素,而大量的移动元素这一操作会严重影响算法的性能,那么如何克服顺序表 操作中的这一缺点呢?这就引出了我们今天将要学习的线性表的链式存储之【单链表】。【2】线性表的链式存储不需要使用地址连续的的存储单元,也不需要逻辑上相邻的元素之间,物理位置上也相邻,它是通过“链”, 即指针建立起数据元素之间的逻辑关系,因此,对线性表的插入、删除不需要移动元素,只需要修改相应的指针即可。【3】链式存储:不要求逻辑上相邻的元素在物理位置上也相邻,借助指针来表示元素之间的逻辑关系,其优点是:不出出现内存的 碎片现象,充分利用了内存中的所有存储单元;缺点是:每个数据元素节点占用较多的存储空间,并且只能实现顺序存储,不 能实现【随机存取】。【4】顺序存储:要求逻辑上相邻的数据元素之间,物理位置上也必须相邻,元素之间的逻辑关系由存储单元之间的邻接关系表示。 其优点是:每个元素占用较少的存储空间,并且可以实现随机存取;缺点是:只能使用相邻的一整块存储单元,因此,可能会 产生较多的碎片现象。单链表: 【1】【单链表】:线性表的链式存储称为单链表,它是通过一组任意的存储单元来存储线性表中的数据元素的。【2】为了建立起数据元素之间的线性关系,对每个链表的结点,除了存放元素自身的信息之外,还需要存放一个指向其后继的指针。 单链表的结点一般分为两个域,【数据域】和【指针域】。*************************************************************************************************************************/#include<iostream>#include<string>using namespace std;/*************************************************************************************************************************单链表的11中算法: 【1】初始化单链表的操作 【2】头插法建立单链表 【3】尾插法建立单链表 【4】打印单链表,单链表的遍历 【5】清除线性表中的所有元素,即释放单链表pHead中所有的结点,使之成为一个空表 【6】返回单链表的实际长度 【7】检查单链表是否为空,若为空,则返回1,否则返回0 【8】按序号查找结点值 【9】按值查找表结点 【10】插入结点操作 【11】删除结点操作**************************************************************************************************************************/typedef int ElemType;/*************************************************************************************************************************模块说明: 单链表中,结点类型的描述**************************************************************************************************************************/typedef struct LNode{ElemType data; //【1】数据域struct LNode* next; //【2】指针域}LNode,*LinkList;/*************************************************************************************************************************函数原型: void InitList(LinkList& pHead)函数说明: 【1】初始化单链表的操作【2】pHead是指向单链表头结点的指针,用来接收主程序中待初始化单链表的头指针变量**************************************************************************************************************************/void InitList(LinkList& pHead){pHead = (LinkList)std::malloc(sizeof(LNode)); //【1】创建头结点pHead->next = NULL; //【2】建立空的单链表std::cout<<"【NOTICE】InitList函数被执行,初始化一个空单链表成功!"<<std::endl;}/*************************************************************************************************************************函数原型: LinkList CreatListHead(LinkList& pHead)函数说明: 【1】通常用一个【头指针】来标识一个单链表,如单链表L,头指针为"NULL"时,则表示一个空表。此外,为了操作上的方便,在单 链表第一个结点之前附加一个结点,称为【头结点】。【2】采用头插法建立单链表 该方法从一个空表开始,生成新结点,并将读取到的数据存放到新结点的数据域中,然后将新结点插入到当前链表的表头,即 头结点之后。【3】采用头插法建立单链表,读入数据的顺序与生成的链表中元素的顺序是相反的。**************************************************************************************************************************/LinkList CreatListHead(LinkList& pHead){LNode* insertNode = NULL;int insertData = 0;std::cout<<"【NOTICE】请输入单链表第一个要插入结点的数据insertData:";std::cout<<std::endl;std::cin>>insertData; //【1】输入新结点数据域的值while(insertData!=9999){insertNode = (LNode*)std::malloc(sizeof(LNode)); //【2】创建新结点insertNode->data = insertData;insertNode->next = pHead->next;pHead->next = insertNode;std::cout<<"【NOTICE】请输入下一个结点数据域的数据"<<std::endl;std::cin>>insertData;}//whilereturn pHead;}/*************************************************************************************************************************函数原型: LinkList CreatListTail(LinkList& pHead)函数说明: 【1】尾插法建立单链表。【2】该方法是将新结点插入到当前链表的表尾,为此,必须增加一个尾指针r,使其始终指向当前链表的尾结点。**************************************************************************************************************************/LinkList CreatListTail(LinkList& pHead){int insertData = 0; //【1】设单链表元素的类型为整形LNode* insertNode = NULL;LNode* pTail = NULL;pTail = pHead; //【3】让表尾指针指向头结点std::cout<<"【NOTICE】请输入单链表第一个要插入结点的数据insertData"<<std::endl;std::cin>>insertData; //【4】输入结点的值while(insertData!=9999){insertNode = (LNode*)std::malloc(sizeof(LNode));insertNode->data = insertData;pTail->next = insertNode;pTail = insertNode;std::cout<<"【NOTICE】请输入下一个结点数据域的数据"<<std::endl;std::cin>>insertData;}//whilepTail->next = NULL;return pHead;}/*************************************************************************************************************************函数原型: void PrintList(LinkList pHead)函数说明: 打印单链表,单链表的遍历**************************************************************************************************************************/void PrintList(LinkList pHead){LNode* pTemp = NULL;pTemp = pHead->next;if(pHead->next==NULL){std::cout<<"【NOTICE】PrintList函数被执行,但是单链表为一个空链表!"<<std::endl;}else{std::cout<<"【NOTICE】单链表中存储的数据如下所示:"<<std::endl;while(pTemp){std::cout<<pTemp->data<<std::endl;pTemp = pTemp->next;}}}//void/*************************************************************************************************************************函数原型: void CleanList(LinkList pHead)函数说明: 清除线性表中的所有元素,即释放单链表pHead中所有的结点,使之成为一个空表。**************************************************************************************************************************/void CleanList(LinkList& pHead){LNode* pNext = NULL;LNode* pTemp = NULL;pTemp = pHead->next;if(pHead->next==NULL){std::cout<<"【NOTICE】CleanList函数执行,链表为空!"<<std::endl;}while (pTemp!=NULL){pNext = pTemp->next; //【1】保存下一个结点的指针std::free(pTemp);pTemp = pNext; //【2】表头后移}std::cout<<"【NOTICE】CleanList函数执行完毕,链表已经清除!"<<std::endl;pHead->next = NULL;}//void/*************************************************************************************************************************函数原型: int SizeList(LinkList pHead)函数说明: 返回单链表的实际长度**************************************************************************************************************************/int SizeList(LinkList pHead){int iSize = 0;LNode* pTemp = NULL;pTemp = pHead->next;while (pTemp!=NULL){iSize++;pTemp = pTemp->next;}std::cout<<"【NOTICE】SizeList函数已经执行,链表的长度为 = "<<iSize<<std::endl;return iSize;}/*************************************************************************************************************************函数原型: bool isEmptyList(LNode* pHead)函数说明: 检查单链表是否为空,若为空,则返回1,否则返回0**************************************************************************************************************************/bool IsEmpty(LinkList pHead){LNode* pTemp = NULL;pTemp = pHead->next;if(pHead->next==NULL){std::cout<<"【NOTICE】IsEmpty函数执行成功,链表为空!"<<std::endl;return true;}else{std::cout<<"【NOTICE】IsEmpty函数执行成功,链表非空!"<<std::endl;return false;}}/*************************************************************************************************************************函数原型: LNode* GetElement(LinkList pHead,int i)函数说明: 【1】按序号查找结点值【2】在单链表中从第一个结点出发,顺着指针域逐个往下搜索,直到找到第i个结点为止,否则返回最后一个结点指针域NULL【3】本算法取出单链表L(带头结点)中第i个位置的结点指针**************************************************************************************************************************/LNode* GetElement(LinkList pHead,int iPos){int iCount = 0;LNode* pTemp = NULL;pTemp = pHead->next;if(iPos<1) //【1】位置合法性检查{std::cout<<"【NOTICE】GetElement函数执行成功,iPos位置非法!"<<std::endl;std::system("pause");std::exit(1);}if(pHead->next==NULL) //【2】单链表是否为空{std::cout<<"【NOTICE】GetElement函数执行成功,链表为空!"<<std::endl;std::system("pause");std::exit(1);}while (pTemp!=NULL){++iCount;if(iCount==iPos){break;}pTemp = pTemp->next;}if(iCount<iPos){std::cout<<"【NOTICE】GetElement函数执行成功,iPos值超出链表长度!"<<std::endl;std::system("pause");std::exit(1);}return pTemp;}/*************************************************************************************************************************函数原型: LNode* LocateElem(LinkList pHead,ElemType x)函数说明: 【1】按值查找表结点【2】从单链表第一个结点开始,由前往后依次比较表中各结点数据域的值,,若某结点数据域的值相等,则返回该节点的指针。 若整个单链表中没有这样的结点,则返回NULL.**************************************************************************************************************************/LNode* LocateElem(LinkList pHead,ElemType x){LNode* pTemp = NULL;pTemp = pHead->next;if(pHead->next == NULL){std::cout<<"【NOTICE】LocateElem函数执行完毕,链表为空!"<<std::endl;std::system("pause");return NULL;}while((pTemp->data!=x)&&(pTemp!=NULL)){pTemp = pTemp->next;}if((pTemp->data!=x)&&(pTemp->next==NULL)){std::cout<<"【NOTICE】LocateElem函数执行完毕,在链表中没有找到X值!!"<<std::endl;std::system("pause");std::exit(1);}return pTemp;}/*************************************************************************************************************************函数原型: bool InsertList(LinkList& pHead,int i,ElemType x)函数说明: 【1】插入结点操作【2】插入操作是将值为X的新结点插入到单链表pHead的第i个位置上。【3】插入操作的步骤: (1)先检查插入位置的合法性 (2)找到待插入位置的前驱结点,即第i-1个结点 (3)再在其后插入位置的新结点。**************************************************************************************************************************/bool InsertList(LinkList& pHead,int iPos,ElemType x){if(iPos<1){std::cout<<"【NOTICE】InsertList函数被执行,但是元素插入的位置不合法!"<<std::endl;std::system("pause");return false;}LNode* pTemp = NULL; LNode* pInsertNode = NULL;pInsertNode = (LNode*)std::malloc(sizeof(LNode));pInsertNode->data = x;pTemp = GetElement(pHead,iPos-1);pInsertNode->next = pTemp->next;pTemp->next = pInsertNode;std::cout<<"【NOTICE】InsertList函数被执行,插入成功!"<<std::endl;return true;}/*************************************************************************************************************************函数原型: bool DeleteList(LinkList& pHead,int iPos)函数说明: 【1】删除结点操作【2】删除结点操作是将单链表pHead的第i个位置上的结点删除【3】删除操作的步骤: (1)先检查删除位置的合法性 (2)然后查找表中第iPos-1个结点,即被删除结点的前驱结点 (3)再将其删除**************************************************************************************************************************/bool DeleteList(LinkList& pHead,int iPos){if(iPos<1){std::cout<<"【NOTICE】DeleteList函数被执行,但是删除元素的位置不合法!"<<std::endl;std::system("pause");return false;}LNode* pTemp = NULL;LNode* pDelete= NULL;pTemp = GetElement(pHead,iPos-1);pDelete= GetElement(pHead,iPos);pTemp->next = pDelete->next;std::free(pDelete);std::cout<<"【NOTICE】DeleteList函数被执行,删除成功!"<<std::endl;return true;}int main(){LinkList pHead = NULL;LinkList pTail = NULL;int iLength = 0;ElemType posElem;InitList(pHead);PrintList(pHead);CreatListHead(pHead);PrintList(pHead);InitList(pTail);CreatListTail(pTail);PrintList(pTail);LNode* pValue = NULL;pValue = GetElement(pTail,2);std::cout<<"【NOTICE】单链表中的第二个元素的值 = "<<pValue->data<<std::endl;SizeList(pTail);bool flagEmpty = true;flagEmpty = IsEmpty(pTail);if(flagEmpty){std::cout<<"【NOTICE】单链表为空表!"<<std::endl;}else{std::cout<<"【NOTICE】单链表不为空!"<<std::endl;}LNode* pData = NULL;pData = LocateElem(pTail,2);std::cout<<"【NOTICE】查找出来的值 = "<<pData->data<<std::endl;InsertList(pTail,2,8888);PrintList(pTail);CleanList(pTail);PrintList(pTail);SizeList(pTail);std::system("pause");return 0;}
阅读全文
0 0
- 【Data_Structure笔记2】线性表的链式存储【单链表】
- 【Data_Structure笔记1】线性表的顺序存储【顺序表】
- [学习笔记]线性表的链式存储
- 线性表的链式存储结构-单链表
- 线性表的链式存储结构---单链表
- 线性表的链式存储结构--单链表
- 线性表的链式存储结构:单链表
- 2--线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 线性表的链式存储
- 《线性表的链式存储》
- 线性表的链式存储
- 新概念,数字游民面临的一些挑战和应对举措
- 数据库事务 和spring事务
- Hadoop,Spark: 通过Yarn logs命令收集已完成的Job日志
- 矩阵快速幂
- java的时间格式转换
- 【Data_Structure笔记2】线性表的链式存储【单链表】
- Struts2基于配置校验的内置类型及使用实例
- 问题记事:使用oracle 出现invalid uesr.table.column,table.column
- 系统相关功能开发(七)-系统信息
- jQuery源码学习笔记(02)
- 自律以自救
- 九、 通用工具 ----smart Pointer(智能指针)---weak_ptr
- 551. Student Attendance Record I
- 工作日记2017.08.25 MongoDB 聚合查询 aggregate