C++ 链表,链表各种方法实现原理

简介: C++ 链表,链表各种方法实现原理

我们在上一章节中讲解到了C++vector容器以及vector容器的各种方法实现原理,我们在这一章节讲解一下链表以及链表的各种方法操作原理。

数组为我们在编程的时候提供了很大的便利,但是有时候我们定义的数组不能满足我们的需求,我们需要一个可变数组来存储我们的数据,我们存储多大数据,就为我们分配多少内存空间,这时候链表就显得尤为重要了。

链表的内部结构其实很简单,就是定义一个结构体,该结构体内不仅存储了我们需要的数据,而且存储了下一个结构的指针,通过指针,让各个元素连接起来,这就是链表。这里给出一张图帮助大家理解

链表实现源码

这里给出链表的各种方法实现源码,源码中注释写得很清楚,相信大家能够理解:

#include <iostream>
#include<windows.h>
using namespace std;
#define success 1
#define error 0
template <class T_ELE>
class LinkedList{
public:
  LinkedList();
  ~LinkedList();
  bool IsEmpty();     //判断链表是否为空
  DWORD clear();      //清空链表
  DWORD GetElement(IN DWORD dwIndex,OUT T_ELE& Element);       //根据索引获取元素
  DWORD GetElementIndex(IN T_ELE&Element);     //根据内容获取索引
  DWORD Insert(IN T_ELE& Element);        //在链表尾部新增元素
  DWORD Insert(IN DWORD dwIndex,IN T_ELE& Element);   //在指定位置插入元素
  DWORD Delete(IN DWORD dwIndex);    //根据索引删除元素
  DWORD GetSize();   //获取链表中元素的数量
private:
  typedef struct _NODE{
    T_ELE Data;    //链表数据
    _NODE* pNext;  //下一个数据指针
  }NODE,*PNODE;
private:
  PNODE m_pList;    //链表头指针
  DWORD m_dwLength; //当前链表元素数量 
};
//无参构造函数,初始化成员 
template <class T_ELE>
LinkedList<T_ELE>::LinkedList()
:m_pList(NULL),m_dwLength(0){
  cout<<"构造函数完成。"<<endl;
}
//析构函数
template <class T_ELE>
LinkedList<T_ELE>::~LinkedList(){
  clear();
  cout<<"析构函数完成。"<<endl;
}
//判断链表是否为空 
template <class T_ELE>
bool LinkedList<T_ELE>::IsEmpty(){
  if((m_dwLength = 0 || m_dwLength) = 0){
    cout<<"链表为空!"<<endl;
    return error;
  }else{
    cout<<"链表不为空,将继续执行。"<<endl;
    return success; 
  }
}
//链表尾部新增节点
template <class T_ELE>
DWORD LinkedList<T_ELE>::Insert(IN T_ELE& Element){
  PNODE pNewNode = new NODE;
  memset(pNewNode,0,sizeof(NODE));
  memcpy(pNewNode,&Element,sizeof(T_ELE));
  pNewNode->pNext = 0;
  //判断列表是否为空,如果为空,则从0新增元素
  PNODE ptemp = m_pList;
  if(IsEmpty()){
    m_pList = pNewNode;
    m_dwLength++;
    return success;
  }else{
    for(int i = 0;i < m_dwLength-1;i++){
      ptemp = ptemp->pNext;
      if(ptemp = NULL){
        cout<<"检测本结构下一个指针为0"<<endl;
      }
    }
  }
  ptemp->pNext = pNewNode;
  m_dwLength++;
  cout<<"表尾新增节点成功。"<<endl;
}
//新增节点到指定位置
template <class T_ELE>
DWORD LinkedList<T_ELE>::Insert(IN DWORD dwIndex,IN T_ELE& Element){
  PNODE pNewNode = new NODE;
  memset(pNewNode,0,sizeof(NODE));
  memcpy(pNewNode,Element,sizeof(T_ELE));
  pNewNode->pNext = 0;
  //判断链表是否为空,如果指针为空,并且Index为0,将在0的位置新增 
  if(IsEmpty){
    m_pList =  pNewNode;
    m_dwLength++;
    return success;
    cout<<"在索引值为0的位置新增元素成功。"<<endl; 
  }
  //判断索引值是否有效
  if(dwIndex < 0 || dwIndex>m_dwLength){
    cout<<"索引值无效!"<<endl;
    return error;
  }
  //如果索引值为0,则将链表头指针指向new的内存,并且将pNext指向原来索引值为0的元素
  pNewNode->m_List;
  m_pList = pNewNode;
  m_dwLength++;
  return success;
  //如果索引值为表尾
  if(dwIndex = m_dwLength){
    Insert(Element);
    return success; 
  }
  //如果索引在链表中
  PNODE ptemp = m_pList;
  for(int i = 0;i < dwIndex-1;i++){
    ptemp = ptemp->pNext;
  }
  pNewNode->pNext = ptemp->pNext;
  ptemp->pNext = pNewNode;
  cout<<"在"<<dwIndex<<"的位置新增元素成功。"<<endl; 
}
//根据索引删除元素
template <class T_ELE>
DWORD LinkedList<T_ELE>::Delete(IN DWORD dwIndex){
  //如果索引为0
  m_pList = m_pList->pNext;
  delete m_pList;
  m_dwLength--; 
  cout<<"删除索引为0的元素已删除。"<<endl;
  //如果索引不为0
  //判断索引是否有效
  if(dwIndex<0 || dwIndex>m_dwLength){
    cout<<"索引"<<dwIndex<<"无效!"<<endl;
    return error;
  }
  //如果索引为链表尾部
   if(dwIndex = m_dwLength){
    PNODE ptemp;
    for(int i = 0;i<dwIndex - 1;i++){
      ptemp = ptemp->pNext;
     }
     delete ptemp->pNext;
     ptemp->pNext = 0;
     cout<<"索引"<<dwIndex<<"元素已删除。"<<endl;
   }
  //如果索引为链表中间位置 
  PNODE ptemp1= m_pList;
  for(int i = 0;i<dwIndex-1;i++){
    ptemp1 = ptemp1->pNext;
  }
  PNODE ptemp2 = ptemp1->pNext;
  ptemp1->pNext = ptemp2->pNext;
  delete ptemp2;
  m_dwLength--;
  cout<<"索引"<<dwIndex<<"的元素已删除。"<<endl;
  return success;
}
//获取链表中元素数量
template <class T_ELE>
DWORD LinkedList<T_ELE>::GetSize(){
  cout<<"当前链表元素个数为"<<m_dwLength<<endl;
  return m_dwLength;
}
//清除链表元素
template <class T_ELE>
DWORD LinkedList<T_ELE>::clear(){
  PNODE ptemp1 = m_pList;
  PNODE ptemp2 = NULL;
  for(int i = 0;i < m_dwLength;i++){
    ptemp2 = ptemp1->pNext;
    delete ptemp1;
  }
} 
//测试函数
void Test(){
  LinkedList<int> v1;
  int a=5;
  v1.Insert(a);
  } 
int main(){
  Test();
  return 0;
}
相关文章
|
1月前
|
存储 Java
HashMap之链表转红黑树(树化 )-treefyBin方法源码解读(所有涉及到的方法均有详细解读,欢迎指正)
本文详细解析了Java HashMap中链表转红黑树的机制,包括树化条件(链表长度达8且数组长度≥64)及转换流程,确保高效处理大量数据。
71 1
|
2月前
|
编译器 API C语言
超级好用的C++实用库之跨平台实用方法
超级好用的C++实用库之跨平台实用方法
39 6
|
2月前
|
JavaScript 前端开发 Java
通过Gtest访问C++静态、私有、保护变量和方法
通过Gtest访问C++静态、私有、保护变量和方法
67 0
|
3月前
|
C++
C++ 避免多重定义的方法
C++ 避免多重定义的方法
59 0
|
3月前
|
Dart API C语言
Dart ffi 使用问题之想在C/C++中创建异步线程来调用Dart方法,如何操作
Dart ffi 使用问题之想在C/C++中创建异步线程来调用Dart方法,如何操作
|
4月前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
|
5月前
|
C++
C/C++内存管理(2):`new`和`delete`的实现原理
C/C++内存管理(2):`new`和`delete`的实现原理
|
5月前
|
存储 编译器 程序员
C++语言速成方法
C++语言速成方法
|
5月前
|
C++ UED 开发者
逆向学习 MFC 篇:视图分割和在 C++ 的 Windows 窗口程序中添加图标的方法
逆向学习 MFC 篇:视图分割和在 C++ 的 Windows 窗口程序中添加图标的方法
76 0
|
5月前
|
C++ Python
UE C++ 链表
UE C++ 链表